source: trunk/modules/vci_mem_cache_v4/caba/source/src/vci_mem_cache_v4.cpp @ 200

Last change on this file since 200 was 200, checked in by alain, 12 years ago
  • Property svn:eol-style set to native
  • Property svn:keywords set to "Author Date Id Rev URL Revision"
  • Property svn:mime-type set to text/plain
File size: 229.6 KB
RevLine 
[184]1 /* -*- c++ -*-
[2]2 * File         : vci_mem_cache_v4.cpp
3 * Date         : 30/10/2008
4 * Copyright    : UPMC / LIP6
5 * Authors      : Alain Greiner / Eric Guthmuller
6 *
7 * SOCLIB_LGPL_HEADER_BEGIN
8 *
9 * This file is part of SoCLib, GNU LGPLv2.1.
10 *
11 * SoCLib is free software; you can redistribute it and/or modify it
12 * under the terms of the GNU Lesser General Public License as published
13 * by the Free Software Foundation; version 2.1 of the License.
14 *
15 * SoCLib is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18 * Lesser General Public License for more details.
19 *
20 * You should have received a copy of the GNU Lesser General Public
21 * License along with SoCLib; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
23 * 02110-1301 USA
24 *
25 * SOCLIB_LGPL_HEADER_END
26 *
27 * Maintainers: alain eric.guthmuller@polytechnique.edu
28 */
[184]29
[2]30#include "../include/vci_mem_cache_v4.h"
31
[184]32//////   debug services   ///////////////////////////////////////////////////////
33// All debug messages are conditionned by two variables:
34// - compile time : DEBUG_MEMC_*** : defined below
35// - execution time : m_debug_***  : defined by constructor arguments
36//    m_debug_* = (m_debug_ok) and (m_cpt_cycle > m_debug_start_cycle)
37/////////////////////////////////////////////////////////////////////////////////
[134]38
[184]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 
[200]42#define DEBUG_MEMC_SC           1       // detailed trace of SC FSM     
[184]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       
[200]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       
[184]48#define DEBUG_MEMC_TGT_CMD      0       // detailed trace of TGT_CMD FSM       
49#define DEBUG_MEMC_TGT_RSP      0       // detailed trace of TGT_RSP FSM       
50#define DEBUG_MEMC_CLEANUP      0       // detailed trace of CLEANUP FSM       
[140]51
[184]52#define RANDOMIZE_SC            1
[143]53
[2]54namespace soclib { namespace caba {
55
56  const char *tgt_cmd_fsm_str[] = {
[184]57    "TGT_CMD_IDLE",
58    "TGT_CMD_READ",
59    "TGT_CMD_WRITE",
60    "TGT_CMD_ATOMIC",
[2]61  };
62  const char *tgt_rsp_fsm_str[] = {
[184]63    "TGT_RSP_READ_IDLE",
64    "TGT_RSP_WRITE_IDLE",
65    "TGT_RSP_SC_IDLE",
66    "TGT_RSP_XRAM_IDLE",
67    "TGT_RSP_INIT_IDLE",
[2]68    "TGT_RSP_CLEANUP_IDLE",
[184]69    "TGT_RSP_READ",
70    "TGT_RSP_WRITE",
71    "TGT_RSP_SC",
72    "TGT_RSP_XRAM",
73    "TGT_RSP_INIT",
74    "TGT_RSP_CLEANUP",
[2]75  };
76  const char *init_cmd_fsm_str[] = {
[184]77    "INIT_CMD_INVAL_IDLE",
78    "INIT_CMD_INVAL_NLINE",
79    "INIT_CMD_XRAM_BRDCAST",
80    "INIT_CMD_UPDT_IDLE",
81    "INIT_CMD_WRITE_BRDCAST",
82    "INIT_CMD_UPDT_NLINE",
83    "INIT_CMD_UPDT_INDEX",
84    "INIT_CMD_UPDT_DATA",
85    "INIT_CMD_SC_UPDT_IDLE",
86    "INIT_CMD_SC_BRDCAST",
87    "INIT_CMD_SC_UPDT_NLINE",
88    "INIT_CMD_SC_UPDT_INDEX",
89    "INIT_CMD_SC_UPDT_DATA",
[2]90    "INIT_CMD_SC_UPDT_DATA_HIGH",
91  };
92  const char *init_rsp_fsm_str[] = {
[184]93    "INIT_RSP_IDLE",
94    "INIT_RSP_UPT_LOCK",
[2]95    "INIT_RSP_UPT_CLEAR",
[184]96    "INIT_RSP_END",
[2]97  };
98  const char *read_fsm_str[] = {
[184]99    "READ_IDLE",
100    "READ_DIR_LOCK",
101    "READ_DIR_HIT",
102    "READ_HEAP_LOCK",
[2]103    "READ_HEAP_WRITE",
104    "READ_HEAP_ERASE",
[184]105    "READ_HEAP_LAST",
106    "READ_RSP",
107    "READ_TRT_LOCK",
108    "READ_TRT_SET",
109    "READ_TRT_REQ",
[2]110  };
111  const char *write_fsm_str[] = {
[184]112    "WRITE_IDLE",
113    "WRITE_NEXT",
114    "WRITE_DIR_LOCK",
[200]115    "WRITE_DIR_READ",
[184]116    "WRITE_DIR_HIT",
117    "WRITE_UPT_LOCK",
[200]118    "WRITE_UPT_HEAP_LOCK",
[184]119    "WRITE_UPT_REQ",
[200]120    "WRITE_UPT_NEXT",
[184]121    "WRITE_UPT_DEC",
122    "WRITE_RSP",
[200]123    "WRITE_MISS_TRT_LOCK",
124    "WRITE_MISS_TRT_DATA",
125    "WRITE_MISS_TRT_SET",
126    "WRITE_MISS_XRAM_REQ",
127    "WRITE_BC_TRT_LOCK",
128    "WRITE_BC_UPT_LOCK",
129    "WRITE_BC_DIR_INVAL",
130    "WRITE_BC_CC_SEND",
131    "WRITE_BC_XRAM_REQ",
[184]132    "WRITE_WAIT",
[2]133  };
134  const char *ixr_rsp_fsm_str[] = {
[184]135    "IXR_RSP_IDLE",
136    "IXR_RSP_ACK",
[2]137    "IXR_RSP_TRT_ERASE",
[184]138    "IXR_RSP_TRT_READ",
[2]139  };
140  const char *xram_rsp_fsm_str[] = {
[184]141    "XRAM_RSP_IDLE",
142    "XRAM_RSP_TRT_COPY",
143    "XRAM_RSP_TRT_DIRTY",
144    "XRAM_RSP_DIR_LOCK",
145    "XRAM_RSP_DIR_UPDT",
146    "XRAM_RSP_DIR_RSP",
147    "XRAM_RSP_INVAL_LOCK",
148    "XRAM_RSP_INVAL_WAIT",
149    "XRAM_RSP_INVAL",
[2]150    "XRAM_RSP_WRITE_DIRTY",
[184]151    "XRAM_RSP_HEAP_ERASE",
152    "XRAM_RSP_HEAP_LAST",
[138]153    "XRAM_RSP_ERROR_ERASE",
[184]154    "XRAM_RSP_ERROR_RSP",
[2]155  };
156  const char *ixr_cmd_fsm_str[] = {
[184]157    "IXR_CMD_READ_IDLE",
158    "IXR_CMD_WRITE_IDLE",
159    "IXR_CMD_SC_IDLE",
160    "IXR_CMD_XRAM_IDLE",
161    "IXR_CMD_READ_NLINE",
162    "IXR_CMD_WRITE_NLINE",
163    "IXR_CMD_SC_NLINE",
164    "IXR_CMD_XRAM_DATA",
[2]165  };
[184]166  const char *sc_fsm_str[] = {
167    "SC_IDLE",
168    "SC_DIR_LOCK",
169    "SC_DIR_HIT_READ",
[2]170    "SC_DIR_HIT_WRITE",
[184]171    "SC_UPT_LOCK",
[200]172    "SC_UPT_HEAP_LOCK",
[184]173    "SC_UPT_REQ",
174    "SC_UPT_NEXT",
[200]175    "SC_BC_TRT_LOCK",
176    "SC_BC_UPT_LOCK",
177    "SC_BC_DIR_INVAL",
178    "SC_BC_CC_SEND",
179    "SC_BC_XRAM_REQ",
[184]180    "SC_RSP_FAIL",
181    "SC_RSP_SUCCESS",
[200]182    "SC_MISS_TRT_LOCK",
183    "SC_MISS_TRT_SET",
184    "SC_MISS_XRAM_REQ",
185    "SC_WAIT",
[2]186  };
187  const char *cleanup_fsm_str[] = {
[184]188    "CLEANUP_IDLE",
189    "CLEANUP_DIR_LOCK",
190    "CLEANUP_DIR_WRITE",
191    "CLEANUP_HEAP_LOCK",
[2]192    "CLEANUP_HEAP_SEARCH",
[184]193    "CLEANUP_HEAP_CLEAN",
194    "CLEANUP_HEAP_FREE",
195    "CLEANUP_UPT_LOCK",
196    "CLEANUP_UPT_WRITE",
197    "CLEANUP_WRITE_RSP",
198    "CLEANUP_RSP",
[2]199  };
200  const char *alloc_dir_fsm_str[] = {
[184]201    "ALLOC_DIR_READ",
202    "ALLOC_DIR_WRITE",
203    "ALLOC_DIR_SC",
204    "ALLOC_DIR_CLEANUP",
[2]205    "ALLOC_DIR_XRAM_RSP",
206  };
207  const char *alloc_trt_fsm_str[] = {
[184]208    "ALLOC_TRT_READ",
209    "ALLOC_TRT_WRITE",
210    "ALLOC_TRT_SC",
[2]211    "ALLOC_TRT_XRAM_RSP",
[184]212    "ALLOC_TRT_IXR_RSP",
[2]213  };
214  const char *alloc_upt_fsm_str[] = {
[184]215    "ALLOC_UPT_WRITE",
[2]216    "ALLOC_UPT_XRAM_RSP",
217    "ALLOC_UPT_INIT_RSP",
[184]218    "ALLOC_UPT_CLEANUP",
[2]219  };
220  const char *alloc_heap_fsm_str[] = {
[184]221    "ALLOC_HEAP_READ",
222    "ALLOC_HEAP_WRITE",
223    "ALLOC_HEAP_SC",
224    "ALLOC_HEAP_CLEANUP",
[2]225    "ALLOC_HEAP_XRAM_RSP",
226  };
227
228#define tmpl(x) template<typename vci_param> x VciMemCacheV4<vci_param>
229
230  using soclib::common::uint32_log2;
231
232  ////////////////////////////////
233  //    Constructor
234  ////////////////////////////////
235
236  tmpl(/**/)::VciMemCacheV4(
237      sc_module_name name,
238      const soclib::common::MappingTable &mtp,
239      const soclib::common::MappingTable &mtc,
240      const soclib::common::MappingTable &mtx,
241      const soclib::common::IntTab &vci_ixr_index,
242      const soclib::common::IntTab &vci_ini_index,
243      const soclib::common::IntTab &vci_tgt_index,
244      const soclib::common::IntTab &vci_tgt_index_cleanup,
[184]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
251      size_t debug_start_cycle,
252      bool   debug_ok)
[2]253
254    : soclib::caba::BaseModule(name),
255
[184]256    m_debug_start_cycle( debug_start_cycle),
257    m_debug_ok ( debug_ok ),
258
[2]259    p_clk("clk"),
260    p_resetn("resetn"),
261    p_vci_tgt("vci_tgt"),
262    p_vci_tgt_cleanup("vci_tgt_cleanup"),
263    p_vci_ini("vci_ini"),
264    p_vci_ixr("vci_ixr"),
265
266    m_initiators( 1 << vci_param::S ),
267    m_heap_size( heap_size ),
268    m_ways( nways ),
269    m_sets( nsets ),
270    m_words( nwords ),
271    m_srcid_ixr( mtx.indexForId(vci_ixr_index) ),
272    m_srcid_ini( mtc.indexForId(vci_ini_index) ),
273    m_seglist(mtp.getSegmentList(vci_tgt_index)),
274    m_cseglist(mtc.getSegmentList(vci_tgt_index_cleanup)),
275    m_coherence_table( mtc.getCoherenceTable<vci_addr_t>() ),
[141]276    m_transaction_tab_lines(transaction_tab_lines),
277    m_transaction_tab( transaction_tab_lines, nwords ),
278    m_update_tab_lines( update_tab_lines),
279    m_update_tab( update_tab_lines ),
[2]280    m_cache_directory( nways, nsets, nwords, vci_param::N ),
[184]281    m_heap( m_heap_size ),
282
[2]283#define L2 soclib::common::uint32_log2
284    m_x( L2(m_words), 2),
285    m_y( L2(m_sets), L2(m_words) + 2),
286    m_z( vci_param::N - L2(m_sets) - L2(m_words) - 2, L2(m_sets) + L2(m_words) + 2),
287    m_nline( vci_param::N - L2(m_words) - 2, L2(m_words) + 2),
288#undef L2
289
290    //  FIFOs
[200]291
[2]292    m_cmd_read_addr_fifo("m_cmd_read_addr_fifo", 4),
293    m_cmd_read_length_fifo("m_cmd_read_length_fifo", 4),
294    m_cmd_read_srcid_fifo("m_cmd_read_srcid_fifo", 4),
295    m_cmd_read_trdid_fifo("m_cmd_read_trdid_fifo", 4),
296    m_cmd_read_pktid_fifo("m_cmd_read_pktid_fifo", 4),
297
298    m_cmd_write_addr_fifo("m_cmd_write_addr_fifo",8),
299    m_cmd_write_eop_fifo("m_cmd_write_eop_fifo",8),
300    m_cmd_write_srcid_fifo("m_cmd_write_srcid_fifo",8),
301    m_cmd_write_trdid_fifo("m_cmd_write_trdid_fifo",8),
302    m_cmd_write_pktid_fifo("m_cmd_write_pktid_fifo",8),
303    m_cmd_write_data_fifo("m_cmd_write_data_fifo",8),
304    m_cmd_write_be_fifo("m_cmd_write_be_fifo",8),
305
[184]306    m_cmd_sc_addr_fifo("m_cmd_sc_addr_fifo",4),
307    m_cmd_sc_eop_fifo("m_cmd_sc_eop_fifo",4),
308    m_cmd_sc_srcid_fifo("m_cmd_sc_srcid_fifo",4),
309    m_cmd_sc_trdid_fifo("m_cmd_sc_trdid_fifo",4),
310    m_cmd_sc_pktid_fifo("m_cmd_sc_pktid_fifo",4),
311    m_cmd_sc_wdata_fifo("m_cmd_sc_wdata_fifo",4),
[2]312
313    r_tgt_cmd_fsm("r_tgt_cmd_fsm"),
314   
315    nseg(0),   
[19]316    ncseg(0),   
[2]317
318    r_read_fsm("r_read_fsm"),
[200]319
[2]320    r_write_fsm("r_write_fsm"),
[200]321
[2]322    m_write_to_init_cmd_inst_fifo("m_write_to_init_cmd_inst_fifo",8),
323    m_write_to_init_cmd_srcid_fifo("m_write_to_init_cmd_srcid_fifo",8),
[140]324#if L1_MULTI_CACHE
325    m_write_to_init_cmd_cache_id_fifo("m_write_to_init_cmd_cache_id_fifo",8),
326#endif
[200]327
[2]328    r_init_rsp_fsm("r_init_rsp_fsm"),
329    r_cleanup_fsm("r_cleanup_fsm"),
[200]330
[184]331    r_sc_fsm("r_sc_fsm"),
[200]332
[184]333    m_sc_to_init_cmd_inst_fifo("m_sc_to_init_cmd_inst_fifo",8),
334    m_sc_to_init_cmd_srcid_fifo("m_sc_to_init_cmd_srcid_fifo",8),
[140]335#if L1_MULTI_CACHE
[184]336    m_sc_to_init_cmd_cache_id_fifo("m_sc_to_init_cmd_cache_id_fifo",8),
[140]337#endif
[200]338
[2]339    r_ixr_rsp_fsm("r_ixr_rsp_fsm"),
340    r_xram_rsp_fsm("r_xram_rsp_fsm"),
[200]341
[2]342    m_xram_rsp_to_init_cmd_inst_fifo("m_xram_rsp_to_init_cmd_inst_fifo",8),
343    m_xram_rsp_to_init_cmd_srcid_fifo("m_xram_rsp_to_init_cmd_srcid_fifo",8),
[140]344#if L1_MULTI_CACHE
345    m_xram_rsp_to_init_cmd_cache_id_fifo("m_xram_rsp_to_init_cmd_cache_id_fifo",8),
346#endif
[200]347
[2]348    r_ixr_cmd_fsm("r_ixr_cmd_fsm"),
[200]349
[2]350    r_tgt_rsp_fsm("r_tgt_rsp_fsm"),
[200]351
[2]352    r_init_cmd_fsm("r_init_cmd_fsm"),
[200]353
[2]354    r_alloc_dir_fsm("r_alloc_dir_fsm"),
355    r_alloc_trt_fsm("r_alloc_trt_fsm"),
356    r_alloc_upt_fsm("r_alloc_upt_fsm")
[200]357
[2]358    {
359      assert(IS_POW_OF_2(nsets));
360      assert(IS_POW_OF_2(nwords));
361      assert(IS_POW_OF_2(nways));
362      assert(nsets);
363      assert(nwords);
364      assert(nways);
365
[184]366      // check Transaction table size
367      assert( (uint32_log2(transaction_tab_lines) <= vci_param::T) and
368             "Need more bits for VCI TRDID field");
369
[82]370      // Set the broadcast address with Xmin,Xmax,Ymin,Ymax set to maximum
[116]371      m_broadcast_address = 0x3 | (0x7C1F << (vci_param::N-20));
[2]372
373      // Get the segments associated to the MemCache
374      std::list<soclib::common::Segment>::iterator seg;
375
376      for(seg = m_seglist.begin(); seg != m_seglist.end() ; seg++) {
377        nseg++;
378      }
379      for(seg = m_cseglist.begin(); seg != m_cseglist.end() ; seg++) {
380        ncseg++;
381      }
382
383      m_seg = new soclib::common::Segment*[nseg];
384      size_t i = 0;
385      for ( seg = m_seglist.begin() ; seg != m_seglist.end() ; seg++ ) {
386        m_seg[i] = &(*seg);
387        i++;
388      }
389      m_cseg = new soclib::common::Segment*[ncseg];
390      i = 0;
391      for ( seg = m_cseglist.begin() ; seg != m_cseglist.end() ; seg++ ) {
392          m_cseg[i] = &(*seg);
393          i++;
394      }
395
396      // Memory cache allocation & initialisation
397      m_cache_data = new data_t**[nways];
398      for ( size_t i=0 ; i<nways ; ++i ) {
399        m_cache_data[i] = new data_t*[nsets];
400      }
401      for ( size_t i=0; i<nways; ++i ) {
402        for ( size_t j=0; j<nsets; ++j ) {
403          m_cache_data[i][j] = new data_t[nwords];
404          for ( size_t k=0; k<nwords; k++){
405            m_cache_data[i][j][k]=0;
406          }     
407        }
408      }
409
410      // Allocation for IXR_RSP FSM
[141]411      r_ixr_rsp_to_xram_rsp_rok     = new sc_signal<bool>[m_transaction_tab_lines];
[2]412
413      // Allocation for XRAM_RSP FSM
414      r_xram_rsp_victim_data        = new sc_signal<data_t>[nwords];
415      r_xram_rsp_to_tgt_rsp_data    = new sc_signal<data_t>[nwords];
416      r_xram_rsp_to_ixr_cmd_data    = new sc_signal<data_t>[nwords];
417
418      // Allocation for READ FSM
419      r_read_data                               = new sc_signal<data_t>[nwords];
420      r_read_to_tgt_rsp_data            = new sc_signal<data_t>[nwords];
421
422      // Allocation for WRITE FSM
423      r_write_data                              = new sc_signal<data_t>[nwords];
424      r_write_be                                = new sc_signal<be_t>[nwords];
425      r_write_to_init_cmd_data          = new sc_signal<data_t>[nwords];
426      r_write_to_init_cmd_be            = new sc_signal<be_t>[nwords];
427      r_write_to_ixr_cmd_data       = new sc_signal<data_t>[nwords];
428
[184]429      // Allocation for SC FSM
430      r_sc_to_ixr_cmd_data              = new sc_signal<data_t>[nwords];
431      r_sc_rdata                    = new sc_signal<data_t>[2];
[2]432
433
434      // Simulation
435
436      SC_METHOD(transition);
437      dont_initialize();
438      sensitive << p_clk.pos();
439
440      SC_METHOD(genMoore);
441      dont_initialize();
442      sensitive << p_clk.neg();
443
444    } // end constructor
445
[184]446/////////////////////////////////////////////////////
447tmpl(void)::cache_monitor( vci_addr_t addr )
448/////////////////////////////////////////////////////
449{
450    size_t way = 0;
451    DirectoryEntry entry = m_cache_directory.read(addr, way);
452    if ( (entry.count != m_debug_previous_count) or
453         (entry.valid != m_debug_previous_hit) )
454    {
455    std::cout << " MEMC " << name()
456              << " cache change at cycle " << std::dec << m_cpt_cycles
457              << " for address " << std::hex << addr
458              << " / HIT = " << entry.valid
459              << " / COUNT = " << std::dec << entry.count << std::endl;
460    }
461    m_debug_previous_count = entry.count;
462    m_debug_previous_hit = entry.valid;
463}
[116]464
[184]465//////////////////////////////////////////////////
466tmpl(void)::print_trace()
467//////////////////////////////////////////////////
468{
469    std::cout << "MEMC " << name() << std::endl;
470    std::cout << "  "  << tgt_cmd_fsm_str[r_tgt_cmd_fsm]
471              << " | " << tgt_rsp_fsm_str[r_tgt_rsp_fsm]
472              << " | " << read_fsm_str[r_read_fsm]
473              << " | " << write_fsm_str[r_write_fsm]
474              << " | " << sc_fsm_str[r_sc_fsm]
475              << " | " << cleanup_fsm_str[r_cleanup_fsm] << std::endl;
476    std::cout << "  "  << init_cmd_fsm_str[r_init_cmd_fsm]
477              << " | " << init_rsp_fsm_str[r_init_rsp_fsm]
478              << " | " << ixr_cmd_fsm_str[r_ixr_cmd_fsm]
479              << " | " << ixr_rsp_fsm_str[r_ixr_rsp_fsm]
480              << " | " << xram_rsp_fsm_str[r_xram_rsp_fsm] << std::endl;
481}
[116]482
[184]483/////////////////////////////////////////
484tmpl(void)::print_stats()
485/////////////////////////////////////////
486{
[2]487    std::cout << "----------------------------------" << std::dec << std::endl;
488    std::cout << "MEM_CACHE " << m_srcid_ini << " / Time = " << m_cpt_cycles << std::endl
[141]489              << "- READ RATE            = " << (double)m_cpt_read/m_cpt_cycles << std::endl
490              << "- READ TOTAL           = " << m_cpt_read << std::endl
491              << "- READ MISS RATE       = " << (double)m_cpt_read_miss/m_cpt_read << std::endl
492              << "- WRITE RATE           = " << (double)m_cpt_write/m_cpt_cycles << std::endl
493              << "- WRITE TOTAL          = " << m_cpt_write << std::endl
494              << "- WRITE MISS RATE      = " << (double)m_cpt_write_miss/m_cpt_write << std::endl
495              << "- WRITE BURST LENGTH   = " << (double)m_cpt_write_cells/m_cpt_write << std::endl
496              << "- WRITE BURST TOTAL    = " << m_cpt_write_cells << std::endl
497              << "- REQUESTS TRT FULL    = " << m_cpt_trt_full << std::endl
498              << "- READ TRT BLOKED HIT  = " << m_cpt_trt_rb << std::endl
499              << "- UPDATE RATE          = " << (double)m_cpt_update/m_cpt_cycles << std::endl
500              << "- UPDATE ARITY         = " << (double)m_cpt_update_mult/m_cpt_update << std::endl
501              << "- INVAL MULTICAST RATE = " << (double)(m_cpt_inval-m_cpt_inval_brdcast)/m_cpt_cycles << std::endl
502              << "- INVAL MULTICAST ARITY= " << (double)m_cpt_inval_mult/(m_cpt_inval-m_cpt_inval_brdcast) << std::endl
503              << "- INVAL BROADCAST RATE = " << (double)m_cpt_inval_brdcast/m_cpt_cycles << std::endl
504              << "- SAVE DIRTY RATE      = " << (double)m_cpt_write_dirty/m_cpt_cycles << std::endl
505              << "- CLEANUP RATE         = " << (double)m_cpt_cleanup/m_cpt_cycles << std::endl
506              << "- LL RATE              = " << (double)m_cpt_ll/m_cpt_cycles << std::endl
507              << "- SC RATE              = " << (double)m_cpt_sc/m_cpt_cycles << std::endl;
[184]508}
[2]509
510  /////////////////////////////////
511  tmpl(/**/)::~VciMemCacheV4()
512    /////////////////////////////////
513  {
514    for(size_t i=0; i<m_ways ; i++){
515      for(size_t j=0; j<m_sets ; j++){
516        delete [] m_cache_data[i][j];
517      }
518    }
519    for(size_t i=0; i<m_ways ; i++){
520      delete [] m_cache_data[i];
521    }
522    delete [] m_cache_data;
523    delete [] m_coherence_table;
524
525    delete [] r_ixr_rsp_to_xram_rsp_rok;
526
527    delete [] r_xram_rsp_victim_data;
528    delete [] r_xram_rsp_to_tgt_rsp_data;
529    delete [] r_xram_rsp_to_ixr_cmd_data;
530
531    delete [] r_read_data;
532    delete [] r_read_to_tgt_rsp_data;
533
534    delete [] r_write_data;
535    delete [] r_write_be;
536    delete [] r_write_to_init_cmd_data;
537  }
538
[184]539//////////////////////////////////
540tmpl(void)::transition()
541//////////////////////////////////
542{
[2]543    using soclib::common::uint32_log2;
[184]544
[2]545    //  RESET         
546    if ( ! p_resetn.read() ) {
547
548      //     Initializing FSMs
549      r_tgt_cmd_fsm     = TGT_CMD_IDLE;
550      r_tgt_rsp_fsm     = TGT_RSP_READ_IDLE;
551      r_init_cmd_fsm    = INIT_CMD_INVAL_IDLE;
552      r_init_rsp_fsm    = INIT_RSP_IDLE;
[184]553      r_read_fsm            = READ_IDLE;
554      r_write_fsm           = WRITE_IDLE;
555      r_sc_fsm          = SC_IDLE;
[2]556      r_cleanup_fsm     = CLEANUP_IDLE;
557      r_alloc_dir_fsm   = ALLOC_DIR_READ;
558      r_alloc_trt_fsm   = ALLOC_TRT_READ;
559      r_alloc_upt_fsm   = ALLOC_UPT_WRITE;
560      r_ixr_rsp_fsm     = IXR_RSP_IDLE;
561      r_xram_rsp_fsm    = XRAM_RSP_IDLE;
562      r_ixr_cmd_fsm     = IXR_CMD_READ_IDLE;
563
[184]564      m_debug_global         = false;
565      m_debug_tgt_cmd_fsm    = false;
566      m_debug_tgt_rsp_fsm    = false;
567      m_debug_init_cmd_fsm   = false;
568      m_debug_init_rsp_fsm   = false;
569      m_debug_read_fsm       = false;
570      m_debug_write_fsm      = false;
571      m_debug_sc_fsm         = false;
572      m_debug_cleanup_fsm    = false;
573      m_debug_ixr_cmd_fsm    = false;
574      m_debug_ixr_rsp_fsm    = false;
575      m_debug_xram_rsp_fsm   = false;
576      m_debug_previous_hit   = false;
577      m_debug_previous_count = 0;
578
[2]579      //  Initializing Tables
580      m_cache_directory.init();
581      m_transaction_tab.init();
[184]582      m_heap.init();
[2]583
584      // initializing FIFOs and communication Buffers
585
586      m_cmd_read_addr_fifo.init();
587      m_cmd_read_length_fifo.init();
588      m_cmd_read_srcid_fifo.init();
589      m_cmd_read_trdid_fifo.init();
590      m_cmd_read_pktid_fifo.init();
591
592      m_cmd_write_addr_fifo.init();
593      m_cmd_write_eop_fifo.init();
594      m_cmd_write_srcid_fifo.init();
595      m_cmd_write_trdid_fifo.init();
596      m_cmd_write_pktid_fifo.init();
597      m_cmd_write_data_fifo.init();
598
[184]599      m_cmd_sc_addr_fifo.init();
600      m_cmd_sc_srcid_fifo.init();
601      m_cmd_sc_trdid_fifo.init();
602      m_cmd_sc_pktid_fifo.init();
603      m_cmd_sc_wdata_fifo.init();
604      m_cmd_sc_eop_fifo.init();
[2]605
[184]606      r_read_to_tgt_rsp_req                 = false;
607      r_read_to_ixr_cmd_req                 = false;
[2]608
609      r_write_to_tgt_rsp_req            = false;
610      r_write_to_ixr_cmd_req            = false;
611      r_write_to_init_cmd_multi_req         = false;
612      r_write_to_init_cmd_brdcast_req   = false;
613      r_write_to_init_rsp_req           = false;
614      m_write_to_init_cmd_inst_fifo.init();
615      m_write_to_init_cmd_srcid_fifo.init();
[140]616#if L1_MULTI_CACHE
617      m_write_to_init_cmd_cache_id_fifo.init();
618#endif
[2]619
[184]620      r_cleanup_to_tgt_rsp_req          = false;
[2]621
[184]622      r_init_rsp_to_tgt_rsp_req         = false;
[2]623
[184]624      r_sc_to_tgt_rsp_req                   = false;
625      r_sc_cpt                          = 0;
626      r_sc_lfsr                         = -1;
627      r_sc_to_ixr_cmd_req                   = false;
628      r_sc_to_init_cmd_multi_req            = false;
629      r_sc_to_init_cmd_brdcast_req          = false;
630      m_sc_to_init_cmd_inst_fifo.init();
631      m_sc_to_init_cmd_srcid_fifo.init();
[140]632#if L1_MULTI_CACHE
[184]633      m_sc_to_init_cmd_cache_id_fifo.init();
[140]634#endif
[2]635
[141]636      for(size_t i=0; i<m_transaction_tab_lines ; i++){
[2]637        r_ixr_rsp_to_xram_rsp_rok[i] = false;
638      }
639
640      r_xram_rsp_to_tgt_rsp_req             = false;
641      r_xram_rsp_to_init_cmd_multi_req      = false;
642      r_xram_rsp_to_init_cmd_brdcast_req    = false;
643      r_xram_rsp_to_ixr_cmd_req             = false;
644      r_xram_rsp_trt_index                      = 0;
645      m_xram_rsp_to_init_cmd_inst_fifo.init();
646      m_xram_rsp_to_init_cmd_srcid_fifo.init();
[140]647#if L1_MULTI_CACHE
648      m_xram_rsp_to_init_cmd_cache_id_fifo.init();
649#endif
[2]650
651      r_ixr_cmd_cpt         = 0;
652
653      r_copies_limit        = 3;
654
655      // Activity counters
656      m_cpt_cycles                  = 0;
657      m_cpt_read                    = 0;
658      m_cpt_read_miss       = 0;
659      m_cpt_write                   = 0;
660      m_cpt_write_miss      = 0;
661      m_cpt_write_cells     = 0;
662      m_cpt_write_dirty     = 0;
663      m_cpt_update                  = 0;
664      m_cpt_update_mult     = 0;
665      m_cpt_inval_brdcast       = 0;
666      m_cpt_inval                   = 0;
667      m_cpt_inval_mult          = 0;
668      m_cpt_cleanup                 = 0;
669      m_cpt_ll                      = 0;
670      m_cpt_sc                      = 0;
[184]671      m_cpt_trt_full        = 0;
672      m_cpt_trt_rb          = 0;
[2]673
674      return;
675    }
676
677    bool    cmd_read_fifo_put = false;
678    bool    cmd_read_fifo_get = false;
679
680    bool    cmd_write_fifo_put = false;
681    bool    cmd_write_fifo_get = false;
682
[184]683    bool    cmd_sc_fifo_put = false;
684    bool    cmd_sc_fifo_get = false;
[2]685
[140]686    bool    write_to_init_cmd_fifo_put      = false;
687    bool    write_to_init_cmd_fifo_get      = false;
688    bool    write_to_init_cmd_fifo_inst     = false;
689    size_t  write_to_init_cmd_fifo_srcid    = 0;
[184]690
[140]691#if L1_MULTI_CACHE
692    size_t  write_to_init_cmd_fifo_cache_id = 0;
693#endif
[2]694
[140]695    bool    xram_rsp_to_init_cmd_fifo_put      = false;
696    bool    xram_rsp_to_init_cmd_fifo_get      = false;
697    bool    xram_rsp_to_init_cmd_fifo_inst     = false;
698    size_t  xram_rsp_to_init_cmd_fifo_srcid    = 0;
[184]699
[140]700#if L1_MULTI_CACHE
701    size_t  xram_rsp_to_init_cmd_fifo_cache_id = 0;
702#endif
[2]703
[184]704    bool    sc_to_init_cmd_fifo_put      = false;
705    bool    sc_to_init_cmd_fifo_get      = false;
706    bool    sc_to_init_cmd_fifo_inst     = false;
707    size_t  sc_to_init_cmd_fifo_srcid    = 0;
708
[140]709#if L1_MULTI_CACHE
[184]710    size_t  sc_to_init_cmd_fifo_cache_id = 0;
[140]711#endif
[2]712
[184]713m_debug_global       = (m_cpt_cycles > m_debug_start_cycle) and m_debug_ok;
714m_debug_tgt_cmd_fsm  = (m_cpt_cycles > m_debug_start_cycle) and m_debug_ok;
715m_debug_tgt_rsp_fsm  = (m_cpt_cycles > m_debug_start_cycle) and m_debug_ok;
716m_debug_init_cmd_fsm = (m_cpt_cycles > m_debug_start_cycle) and m_debug_ok;
717m_debug_init_rsp_fsm = (m_cpt_cycles > m_debug_start_cycle) and m_debug_ok;
718m_debug_read_fsm     = (m_cpt_cycles > m_debug_start_cycle) and m_debug_ok;
719m_debug_write_fsm    = (m_cpt_cycles > m_debug_start_cycle) and m_debug_ok;
720m_debug_sc_fsm       = (m_cpt_cycles > m_debug_start_cycle) and m_debug_ok;
721m_debug_cleanup_fsm  = (m_cpt_cycles > m_debug_start_cycle) and m_debug_ok;
722m_debug_ixr_cmd_fsm  = (m_cpt_cycles > m_debug_start_cycle) and m_debug_ok;
723m_debug_ixr_rsp_fsm  = (m_cpt_cycles > m_debug_start_cycle) and m_debug_ok;
724m_debug_xram_rsp_fsm = (m_cpt_cycles > m_debug_start_cycle) and m_debug_ok;
725
726
727#if DEBUG_MEMC_GLOBAL   
728if( m_debug_global )
729{
[2]730    std::cout << "---------------------------------------------" << std::dec << std::endl;
731    std::cout << "MEM_CACHE " << m_srcid_ini << " ; Time = " << m_cpt_cycles << std::endl
732      << " - TGT_CMD FSM    = " << tgt_cmd_fsm_str[r_tgt_cmd_fsm] << std::endl
733      << " - TGT_RSP FSM    = " << tgt_rsp_fsm_str[r_tgt_rsp_fsm] << std::endl
734      << " - INIT_CMD FSM   = " << init_cmd_fsm_str[r_init_cmd_fsm] << std::endl
735      << " - INIT_RSP FSM   = " << init_rsp_fsm_str[r_init_rsp_fsm] << std::endl
736      << " - READ FSM       = " << read_fsm_str[r_read_fsm] << std::endl
737      << " - WRITE FSM      = " << write_fsm_str[r_write_fsm] << std::endl
[184]738      << " - SC FSM         = " << sc_fsm_str[r_sc_fsm] << std::endl
[2]739      << " - CLEANUP FSM    = " << cleanup_fsm_str[r_cleanup_fsm] << std::endl
740      << " - IXR_CMD FSM    = " << ixr_cmd_fsm_str[r_ixr_cmd_fsm] << std::endl
741      << " - IXR_RSP FSM    = " << ixr_rsp_fsm_str[r_ixr_rsp_fsm] << std::endl
742      << " - XRAM_RSP FSM   = " << xram_rsp_fsm_str[r_xram_rsp_fsm] << std::endl
743      << " - ALLOC_DIR FSM  = " << alloc_dir_fsm_str[r_alloc_dir_fsm] << std::endl
744      << " - ALLOC_TRT FSM  = " << alloc_trt_fsm_str[r_alloc_trt_fsm] << std::endl
745      << " - ALLOC_UPT FSM  = " << alloc_upt_fsm_str[r_alloc_upt_fsm] << std::endl
746      << " - ALLOC_HEAP FSM = " << alloc_heap_fsm_str[r_alloc_heap_fsm] << std::endl;
[6]747}
[2]748#endif
749
750    ////////////////////////////////////////////////////////////////////////////////////
751    //          TGT_CMD FSM
752    ////////////////////////////////////////////////////////////////////////////////////
753    // The TGT_CMD_FSM controls the incoming VCI command pakets from the processors
754    //
[184]755    // There is 3 types of accepted commands :
[2]756    // - READ    : a READ request has a length of 1 VCI cell. It can be a single word
757    //             or an entire cache line, depending on the PLEN value.
758    // - WRITE   : a WRITE request has a maximum length of 16 cells, and can only
759    //             concern words in a same line.
[184]760    // - SC      : The SC request has a length of 2 cells or 4 cells.
[2]761    ////////////////////////////////////////////////////////////////////////////////////
762
[184]763    switch ( r_tgt_cmd_fsm.read() )
764    {
765        //////////////////
766        case TGT_CMD_IDLE:
767        {
768            if ( p_vci_tgt.cmdval )
769            {
[2]770
[184]771#if DEBUG_MEMC_TGT_CMD
772if( m_debug_tgt_cmd_fsm )
773{
774    std::cout << "  <MEMC.TGT_CMD_IDLE> Receive command from srcid " << p_vci_tgt.srcid.read()
775              << " / for address " << p_vci_tgt.address.read() << std::endl;
776}
777#endif
778                if ( p_vci_tgt.cmd.read() == vci_param::CMD_READ )
779                {
780                    r_tgt_cmd_fsm = TGT_CMD_READ;
781                }
782                else if ( p_vci_tgt.cmd.read() == vci_param::CMD_WRITE )
783                { 
784                    r_tgt_cmd_fsm = TGT_CMD_WRITE;
785                }
786                else if ( p_vci_tgt.cmd.read() == vci_param::CMD_STORE_COND )
787                {
788                    r_tgt_cmd_fsm = TGT_CMD_ATOMIC;
789                }
790                else
791                {
792                    std::cout << "VCI_MEM_CACHE ERROR " << name()
793                              << " TGT_CMD_IDLE state" << std::endl;
794                    std::cout << " illegal VCI command type" << std::endl;
795                    exit(0);
796                }
797            }
798            break;
799        }
800        //////////////////
801        case TGT_CMD_READ:
[2]802        {
[184]803            if ((m_x[(vci_addr_t)p_vci_tgt.address.read()]+(p_vci_tgt.plen.read()>>2)) > 16)
[2]804            {
[184]805                std::cout << "VCI_MEM_CACHE ERROR " << name() << " TGT_CMD_READ state" << std::endl;
806                std::cout << " illegal address/plen combination for VCI read command" << std::endl;
807                exit(0);
808            }
809            if ( !p_vci_tgt.eop.read() )
[2]810            {
[184]811                std::cout << "VCI_MEM_CACHE ERROR " << name() << " TGT_CMD_READ state" << std::endl;
812                std::cout << " read command packets must contain one single flit" << std::endl;
[2]813                exit(0);
814            }
815
[184]816            if ( p_vci_tgt.cmdval && m_cmd_read_addr_fifo.wok() )
817            {
818           
819#if DEBUG_MEMC_TGT_CMD
820if( m_debug_tgt_cmd_fsm )
821{
822    std::cout << "  <MEMC.TGT_CMD_READ> Push into read_fifo:"
823              << " address = " << std::hex << p_vci_tgt.address.read()
824              << " srcid = " << p_vci_tgt.srcid.read()
825              << " trdid = " << p_vci_tgt.trdid.read()
826              << " plen = " << p_vci_tgt.plen.read() << std::endl;
827}
828#endif
829                cmd_read_fifo_put = true;
830                m_cpt_read++;
831                r_tgt_cmd_fsm = TGT_CMD_IDLE;
832            }
833            break;
[2]834        }
835        ///////////////////
[184]836        case TGT_CMD_WRITE:
[2]837        {
[184]838            if ( p_vci_tgt.cmdval && m_cmd_write_addr_fifo.wok() )
839            {
840           
841#if DEBUG_MEMC_TGT_CMD
842if( m_debug_tgt_cmd_fsm )
843{
844    std::cout << "  <MEMC.TGT_CMD_WRITE> Push into write_fifo:"
845              << " address = " << std::hex << p_vci_tgt.address.read()
846              << " srcid = " << p_vci_tgt.srcid.read()
847              << " trdid = " << p_vci_tgt.trdid.read()
848              << " wdata = " << p_vci_tgt.wdata.read()
849              << " be = " << p_vci_tgt.be.read()
850              << " plen = " << p_vci_tgt.plen.read() << std::endl;
851}
852#endif
853                cmd_write_fifo_put = true;
854                if(  p_vci_tgt.eop )  r_tgt_cmd_fsm = TGT_CMD_IDLE;
855            }
856            break;
[2]857        }
858        ////////////////////
[184]859        case TGT_CMD_ATOMIC:
[2]860        {
[184]861            if ( (p_vci_tgt.plen.read() != 8) && (p_vci_tgt.plen.read() != 16) )
862            {
863                std::cout << "VCI_MEM_CACHE ERROR " << name() << " TGT_CMD_ATOMIC state" << std::endl;
864                std::cout << "illegal format for sc command " << std::endl;
865                exit(0);
866            }
867
868            if ( p_vci_tgt.cmdval && m_cmd_sc_addr_fifo.wok() )
869            {
870           
871#if DEBUG_MEMC_TGT_CMD
872if( m_debug_tgt_cmd_fsm )
873{
874    std::cout << "  <MEMC.TGT_CMD_ATOMIC> Pushing command into cmd_sc_fifo:"
875              << " address = " << std::hex << p_vci_tgt.address.read()
876              << " srcid = " << p_vci_tgt.srcid.read()
877              << " trdid = " << p_vci_tgt.trdid.read()
878              << " wdata = " << p_vci_tgt.wdata.read()
879              << " be = " << p_vci_tgt.be.read()
880              << " plen = " << p_vci_tgt.plen.read() << std::endl;
881}
882#endif
883                cmd_sc_fifo_put = true;
884                if( p_vci_tgt.eop ) r_tgt_cmd_fsm = TGT_CMD_IDLE;
885            }
886            break;
[2]887        }
888    } // end switch tgt_cmd_fsm
889
890    /////////////////////////////////////////////////////////////////////////
891    //          INIT_RSP FSM
892    /////////////////////////////////////////////////////////////////////////
[184]893    // This FSM controls the response to the update or inval coherence
[200]894    // requests sent by the memory cache to the L1 caches and update the UPT.
895    //
[184]896    // It can be update or inval requests initiated by the WRITE FSM,
897    // or inval requests initiated by the XRAM_RSP FSM. 
[200]898    // It can also be a direct request from the WRITE FSM.
899    //
[184]900    // The FSM decrements the proper entry in UPT.
901    // It sends a request to the TGT_RSP FSM to complete the pending
902    // write transaction (acknowledge response to the writer processor),
903    // and clear the UPT entry when all responses have been received. 
[2]904    //
905    // All those response packets are one word, compact
906    // packets complying with the VCI advanced format.
907    // The index in the Table is defined in the RTRDID field, and
[184]908    // the transaction type is defined in the UPT entry.
[2]909    /////////////////////////////////////////////////////////////////////
910
[184]911    switch ( r_init_rsp_fsm.read() )
912    {
913        ///////////////////
914        case INIT_RSP_IDLE:   // wait a response for a coherence transaction
[2]915        {
[184]916            if ( p_vci_ini.rspval )
917            {
[2]918
[184]919#if DEBUG_MEMC_INIT_RSP
920if( m_debug_init_rsp_fsm )
921{
922    std::cout <<  "  <MEMC.INIT_RSP_IDLE> Response for UPT entry "
923              << p_vci_ini.rtrdid.read() << std::endl;
924}
925#endif
926                if ( p_vci_ini.rtrdid.read() >= m_update_tab.size() )
927                {
928                    std::cout << "VCI_MEM_CACHE ERROR " << name()
[200]929                              << " INIT_RSP_IDLE state" << std::endl
930                              << "index too large for UPT: "
[184]931                              << " / rtrdid = " << p_vci_ini.rtrdid.read()
932                              << " / UPT size = " << m_update_tab.size() << std::endl;
933                    exit(0);
934                }
935                if ( !p_vci_ini.reop.read() )
936                {
937                    std::cout << "VCI_MEM_CACHE ERROR " << name()
938                              << " INIT_RSP_IDLE state" << std::endl;
939                    std::cout << "all coherence response packets must be one flit" << std::endl;
940                    exit(0);
941                }
[2]942
[184]943                r_init_rsp_upt_index = p_vci_ini.rtrdid.read();
944                r_init_rsp_fsm = INIT_RSP_UPT_LOCK;
945            }
946            else if( r_write_to_init_rsp_req.read() )
947            {
948                r_init_rsp_upt_index = r_write_to_init_rsp_upt_index.read();
949                r_write_to_init_rsp_req = false;
950                r_init_rsp_fsm = INIT_RSP_UPT_LOCK;
951            }
952            break;
[2]953        }
954        ///////////////////////
[184]955        case INIT_RSP_UPT_LOCK: // decrement the number of expected responses
[2]956        {
[184]957            if ( r_alloc_upt_fsm.read() == ALLOC_UPT_INIT_RSP )
958            {
959                size_t count = 0;
960                bool valid  = m_update_tab.decrement(r_init_rsp_upt_index.read(), count);
[2]961
[184]962#if DEBUG_MEMC_INIT_RSP
963if( m_debug_init_rsp_fsm )
964{
965    std::cout << "  <MEMC.INIT_RSP_UPT_LOCK> Decrement the responses counter for UPT:"
966              << " entry = " << r_init_rsp_upt_index.read()
967              << " / rsp_count = " << std::dec << count << std::endl;
[57]968}
[2]969#endif
[184]970                if ( not valid )
971                {
[200]972                    std::cout << "VCI_MEM_CACHE ERROR " << name()
973                              << " INIT_RSP_UPT_LOCK state" << std::endl
974                              << "unsuccessful access to decrement the UPT" << std::endl;
[184]975                    exit(0);
976                }
[2]977
[184]978                if ( count == 0 ) r_init_rsp_fsm = INIT_RSP_UPT_CLEAR;
979                else              r_init_rsp_fsm = INIT_RSP_IDLE;
980            }
981            break;
[2]982        }
983        ////////////////////////
[184]984        case INIT_RSP_UPT_CLEAR:        // clear the UPT entry
[2]985        {
[184]986            if ( r_alloc_upt_fsm.read() == ALLOC_UPT_INIT_RSP )
987            {
988                r_init_rsp_srcid = m_update_tab.srcid(r_init_rsp_upt_index.read());
989                r_init_rsp_trdid = m_update_tab.trdid(r_init_rsp_upt_index.read());
990                r_init_rsp_pktid = m_update_tab.pktid(r_init_rsp_upt_index.read());
991                r_init_rsp_nline = m_update_tab.nline(r_init_rsp_upt_index.read());
992                bool need_rsp    = m_update_tab.need_rsp(r_init_rsp_upt_index.read());
993
994                if ( need_rsp ) r_init_rsp_fsm = INIT_RSP_END;
995                else            r_init_rsp_fsm = INIT_RSP_IDLE;
996
997                m_update_tab.clear(r_init_rsp_upt_index.read());
998
999#if DEBUG_MEMC_INIT_RSP
1000if ( m_debug_init_rsp_fsm )
1001{
1002    std::cout <<  "  <MEMC.INIT_RSP_UPT_CLEAR> Clear UPT entry "
1003              << r_init_rsp_upt_index.read() <<  std::endl;
[57]1004}
[2]1005#endif
[184]1006            }
1007            break;
[2]1008        }
1009        //////////////////
[184]1010        case INIT_RSP_END:      // Post a request to TGT_RSP FSM
[2]1011        {
[184]1012            if ( !r_init_rsp_to_tgt_rsp_req )
1013            {
1014                r_init_rsp_to_tgt_rsp_req   = true;
1015                r_init_rsp_to_tgt_rsp_srcid = r_init_rsp_srcid.read();
1016                r_init_rsp_to_tgt_rsp_trdid = r_init_rsp_trdid.read();
1017                r_init_rsp_to_tgt_rsp_pktid = r_init_rsp_pktid.read();
1018                r_init_rsp_fsm = INIT_RSP_IDLE;
[2]1019
[184]1020#if DEBUG_MEMC_INIT_RSP
1021if ( m_debug_init_rsp_fsm )
1022{
1023    std::cout <<  "  <MEMC.INIT_RSP_END> Request TGT_RSP FSM to send a response to srcid "
1024              << r_init_rsp_srcid.read() <<  std::endl;
1025}
1026#endif
1027            }
1028            break;
[2]1029        }
1030    } // end switch r_init_rsp_fsm
1031
1032    ////////////////////////////////////////////////////////////////////////////////////
1033    //          READ FSM
1034    ////////////////////////////////////////////////////////////////////////////////////
[184]1035    // The READ FSM controls the VCI read requests.
[2]1036    // It takes the lock protecting the cache directory to check the cache line status:
[184]1037    // - In case of HIT
1038    //   The fsm copies the data (one line, or one single word)
[2]1039    //   in the r_read_to_tgt_rsp buffer. It waits if this buffer is not empty.
1040    //   The requesting initiator is registered in the cache directory.
[184]1041    //   If the number of copy is larger than 1, the new copy is registered
1042    //   in the HEAP.
1043    //   If the number of copy is larger than the threshold, the HEAP is cleared,
1044    //   and the corresponding line switches to the counter mode.
1045    // - In case of MISS
1046    //   The READ fsm takes the lock protecting the transaction tab.
[2]1047    //   If a read transaction to the XRAM for this line already exists,
1048    //   or if the transaction tab is full, the fsm is stalled.
[184]1049    //   If a TRT entry is free, the READ request is registered in TRT,
1050    //   it is consumed in the request FIFO, and transmited to the IXR_CMD FSM.
1051    //   The READ FSM returns in the IDLE state as the read transaction will be
1052    //   completed when the missing line will be received.
[2]1053    ////////////////////////////////////////////////////////////////////////////////////
1054
[184]1055    switch ( r_read_fsm.read() )
1056    {
1057        ///////////////
1058        case READ_IDLE:         // waiting a read request
[2]1059        {
[184]1060            if (m_cmd_read_addr_fifo.rok())
1061            {
[134]1062
[184]1063#if DEBUG_MEMC_READ
1064if( m_debug_read_fsm )
1065{
1066    std::cout << "  <MEMC.READ_IDLE> Read request:"
1067              << " srcid = " << std::hex << m_cmd_read_srcid_fifo.read()
1068              << " / address = " << m_cmd_read_addr_fifo.read()
1069              << " / nwords = " << std::dec << m_cmd_read_length_fifo.read() << std::endl;
1070}
1071#endif
1072                r_read_fsm = READ_DIR_LOCK;
1073            }
1074            break;
[2]1075        }
1076        ///////////////////
[184]1077        case READ_DIR_LOCK:     // check directory for hit / miss
[2]1078        {
[184]1079            if ( r_alloc_dir_fsm.read() == ALLOC_DIR_READ )
1080            {
1081                size_t way = 0;
1082                DirectoryEntry entry = m_cache_directory.read(m_cmd_read_addr_fifo.read(), way);
1083
1084                r_read_is_cnt     = entry.is_cnt;
1085                r_read_dirty      = entry.dirty;
1086                r_read_lock           = entry.lock;
1087                r_read_tag            = entry.tag;
1088                r_read_way            = way;
1089                r_read_count      = entry.count;
1090                r_read_copy       = entry.owner.srcid;
1091
[140]1092#if L1_MULTI_CACHE
[184]1093                r_read_copy_cache = entry.owner.cache_id;
[140]1094#endif
[184]1095                r_read_copy_inst  = entry.owner.inst;
1096                r_read_ptr        = entry.ptr;              // pointer to the heap
[2]1097
[184]1098                bool cached_read = (m_cmd_read_trdid_fifo.read() & 0x1);
1099                if(  entry.valid )      // hit
1100                {
1101                    // test if we need to register a new copy in the heap
1102                    if ( entry.is_cnt || (entry.count == 0) || !cached_read )
1103                        r_read_fsm = READ_DIR_HIT;
1104                    else
1105                        r_read_fsm = READ_HEAP_LOCK;
1106                }
1107                else                    // miss
1108                {
1109                    r_read_fsm = READ_TRT_LOCK;
1110                }
1111
1112#if DEBUG_MEMC_READ
1113if( m_debug_read_fsm )
1114{
1115    std::cout << "  <MEMC.READ_DIR_LOCK> Accessing directory: "
1116              << " address = " << std::hex << m_cmd_read_addr_fifo.read()
1117              << " / hit = " << entry.valid
1118              << " / count = " <<std::dec << entry.count
1119              << " / is_cnt = " << entry.is_cnt << std::endl;
1120}
1121#endif
[2]1122            }
[184]1123            break;
[2]1124        }
1125        //////////////////
[184]1126        case READ_DIR_HIT:          //  read data in cache & update the directory
1127                                //  we enter this state in 3 cases:
1128                                //  - the read request is uncachable
1129                                //  - the cache line is in counter mode
1130                                //  - the cache line is valid but not replcated
[2]1131        {
[184]1132            if( r_alloc_dir_fsm.read() == ALLOC_DIR_READ )
1133            {
1134                // signals generation
1135                bool inst_read    = (m_cmd_read_trdid_fifo.read() & 0x2);
1136                bool cached_read  = (m_cmd_read_trdid_fifo.read() & 0x1);
1137                bool is_cnt       = r_read_is_cnt.read();
[2]1138
[184]1139                // read data in the cache
1140                size_t set        = m_y[(vci_addr_t)(m_cmd_read_addr_fifo.read())];
1141                size_t way        = r_read_way.read();
1142                for ( size_t i=0 ; i<m_words ; i++ ) r_read_data[i] = m_cache_data[way][set][i];
[2]1143
[184]1144                // update the cache directory
1145                DirectoryEntry entry;
1146                entry.valid       = true;
1147                entry.is_cnt  = is_cnt;
1148                entry.dirty       = r_read_dirty.read();
1149                entry.tag         = r_read_tag.read();
1150                entry.lock        = r_read_lock.read();
1151                entry.ptr     = r_read_ptr.read();
1152                if (cached_read)  // Cached read => we must update the copies
1153                {
1154                    if (!is_cnt) // Not counter mode
1155                    {
1156                        entry.owner.srcid    = m_cmd_read_srcid_fifo.read();
[140]1157#if L1_MULTI_CACHE
[184]1158                        entry.owner.cache_id = m_cmd_read_pktid_fifo.read();
[140]1159#endif
[184]1160                        entry.owner.inst     = inst_read;
1161                        entry.count          = r_read_count.read() + 1;
1162                    }
1163                    else  // Counter mode
1164                    {
1165                        entry.owner.srcid    = 0;
[140]1166#if L1_MULTI_CACHE
[184]1167                        entry.owner.cache_id = 0;
[140]1168#endif
[184]1169                        entry.owner.inst     = false;
1170                        entry.count          = r_read_count.read() + 1;
1171                    }
1172                }
1173                else  // Uncached read
1174                {
1175                    entry.owner.srcid     = r_read_copy.read();
[140]1176#if L1_MULTI_CACHE
[184]1177                    entry.owner.cache_id  = r_read_copy_cache.read();
[140]1178#endif
[184]1179                    entry.owner.inst      = r_read_copy_inst.read();
1180                    entry.count           = r_read_count.read();
1181                }
[140]1182
[184]1183#if DEBUG_MEMC_READ
1184if( m_debug_read_fsm )
1185{
1186    std::cout << "  <MEMC.READ_DIR_HIT> Update directory entry:"
1187              << " set = " << std::dec << set
1188              << " / way = " << way
1189              << " / owner_id = " << entry.owner.srcid
1190              << " / owner_ins = " << entry.owner.inst
1191              << " / count = " << entry.count
1192              << " / is_cnt = " << entry.is_cnt << std::endl;
[57]1193}
[2]1194#endif
1195
[184]1196                m_cache_directory.write(set, way, entry);
1197                r_read_fsm    = READ_RSP;
1198            }
1199            break;
[2]1200        }
[184]1201        ////////////////////
1202        case READ_HEAP_LOCK:    // read data in cache, update the directory
1203                                // and prepare the HEAP update       
[2]1204        {
[184]1205            if( r_alloc_heap_fsm.read() == ALLOC_HEAP_READ )
1206            {
1207                // enter counter mode when we reach the limit of copies or the heap is full
1208                bool go_cnt = (r_read_count.read() >= r_copies_limit.read()) || m_heap.is_full();
[2]1209
[184]1210                // read data in the cache
1211                size_t set = m_y[(vci_addr_t)(m_cmd_read_addr_fifo.read())];
1212                size_t way = r_read_way.read();
1213                for ( size_t i=0 ; i<m_words ; i++ ) r_read_data[i] = m_cache_data[way][set][i];
1214
1215                // update the cache directory
1216                DirectoryEntry entry;
1217                entry.valid       = true;
1218                entry.is_cnt  = go_cnt;
1219                entry.dirty       = r_read_dirty.read();
1220                entry.tag         = r_read_tag.read();
1221                entry.lock        = r_read_lock.read();
1222                entry.count   = r_read_count.read() + 1;
1223
1224                if (not go_cnt)        // Not entering counter mode
1225                {
1226                    entry.owner.srcid   = r_read_copy.read();
[140]1227#if L1_MULTI_CACHE
[184]1228                    entry.owner.cache_id= r_read_copy_cache.read();
[140]1229#endif
[184]1230                    entry.owner.inst    = r_read_copy_inst.read();
1231                    entry.ptr           = m_heap.next_free_ptr();   // set pointer on the heap
1232                }
1233                else                // Entering Counter mode
1234                {
1235                    entry.owner.srcid   = 0;
[140]1236#if L1_MULTI_CACHE
[184]1237                    entry.owner.cache_id= 0;
[140]1238#endif
[184]1239                    entry.owner.inst    = false;
1240                    entry.ptr           = 0;
1241                }
[2]1242
[184]1243                m_cache_directory.write(set, way, entry);
[2]1244
[184]1245                // prepare the heap update (add an entry, or clear the linked list)
1246                if (not go_cnt)     // not switching to counter mode
1247                {
1248                    // We test if the next free entry in the heap is the last
1249                    HeapEntry heap_entry = m_heap.next_free_entry();
1250                    r_read_next_ptr      = heap_entry.next;
1251                    r_read_last_free     = ( heap_entry.next == m_heap.next_free_ptr() );
1252
1253                    r_read_fsm           = READ_HEAP_WRITE; // add an entry in the HEAP
1254                }
1255                else                    // switching to counter mode
1256                {
1257                    if ( r_read_count.read()>1 )            // heap must be cleared
1258                    {
1259                        HeapEntry next_entry = m_heap.read(r_read_ptr.read());
1260                        r_read_next_ptr      = m_heap.next_free_ptr();
1261                        m_heap.write_free_ptr(r_read_ptr.read());
1262
1263                        if( next_entry.next == r_read_ptr.read() )  // last entry
1264                        {
1265                            r_read_fsm = READ_HEAP_LAST;    // erase the entry
1266                        }
1267                        else                                        // not the last entry
1268                        {
1269                            r_read_ptr = next_entry.next;
1270                            r_read_fsm = READ_HEAP_ERASE;   // erase the list
1271                        }
1272                    }
1273                    else        // the heap is not used / nothing to do
1274                    {
1275                        r_read_fsm = READ_RSP;
1276                    }
[2]1277                }
[184]1278
1279#if DEBUG_MEMC_READ
1280if( m_debug_read_fsm )
1281{
1282    std::cout << "  <MEMC.READ_HEAP_LOCK> Update directory:"
1283              << " tag = " << std::hex << entry.tag
1284              << " set = " << std::dec << set
1285              << " way = " << way
1286              << " count = " << entry.count
1287              << " is_cnt = " << entry.is_cnt << std::endl;
1288}
1289#endif
[2]1290            }
[184]1291            break;
[2]1292        }
[184]1293        /////////////////////
1294        case READ_HEAP_WRITE:       // add a entry in the heap
[2]1295        {
[184]1296            if ( r_alloc_heap_fsm.read() == ALLOC_HEAP_READ )
1297            {
1298                HeapEntry heap_entry;
1299                heap_entry.owner.srcid    = m_cmd_read_srcid_fifo.read();
[140]1300#if L1_MULTI_CACHE
[184]1301                heap_entry.owner.cache_id = m_cmd_read_pktid_fifo.read();
[140]1302#endif
[184]1303                heap_entry.owner.inst     = (m_cmd_read_trdid_fifo.read() & 0x2);
1304
1305                if(r_read_count.read() == 1)    // creation of a new linked list
1306                {
1307                    heap_entry.next         = m_heap.next_free_ptr();
1308                }
1309                else                            // head insertion in existing list
1310                {
1311                    heap_entry.next         = r_read_ptr.read();
1312                }
1313                m_heap.write_free_entry(heap_entry);
1314                m_heap.write_free_ptr(r_read_next_ptr.read());
1315                if(r_read_last_free.read())  m_heap.set_full();
1316
1317                r_read_fsm = READ_RSP;
1318
1319#if DEBUG_MEMC_READ
1320if( m_debug_read_fsm )
1321{
1322    std::cout << "  <MEMC.READ_HEAP_WRITE> Add an entry in the heap:"
1323              << " owner_id = " << heap_entry.owner.srcid
1324              << " owner_ins = " << heap_entry.owner.inst << std::endl;
1325}
1326#endif
[2]1327            }
[184]1328            else
1329            {
1330                std::cout << "VCI_MEM_CACHE ERROR " << name()
1331                          << " READ_HEAP_WRITE state" << std::endl;
1332                std::cout << "Bad HEAP allocation" << std::endl;
1333                exit(0);
[2]1334            }
[184]1335            break;
[2]1336        }
[184]1337        /////////////////////
1338        case READ_HEAP_ERASE:
[2]1339        {
[184]1340            if ( r_alloc_heap_fsm.read() == ALLOC_HEAP_READ )
1341            {
1342                HeapEntry next_entry = m_heap.read(r_read_ptr.read());
1343                if( next_entry.next == r_read_ptr.read() )
1344                {
1345                    r_read_fsm = READ_HEAP_LAST;
1346                }
1347                else
1348                {
1349                    r_read_ptr = next_entry.next;
1350                    r_read_fsm = READ_HEAP_ERASE;
1351                }
1352            }
1353            else
1354            {
1355                std::cout << "VCI_MEM_CACHE ERROR " << name()
1356                          << " READ_HEAP_ERASE state" << std::endl;
1357                std::cout << "Bad HEAP allocation" << std::endl;
1358                exit(0);
[2]1359            }
[184]1360            break;
[2]1361        }
[184]1362        ////////////////////
1363        case READ_HEAP_LAST:
[2]1364        {
[184]1365            if ( r_alloc_heap_fsm.read() == ALLOC_HEAP_READ )
1366            {
1367                HeapEntry last_entry;
1368                last_entry.owner.srcid    = 0;
[140]1369#if L1_MULTI_CACHE
[184]1370                last_entry.owner.cache_id = 0;
[140]1371#endif
[184]1372                last_entry.owner.inst     = false;
1373
1374                if(m_heap.is_full())
1375                {
1376                    last_entry.next       = r_read_ptr.read();
1377                    m_heap.unset_full();
1378                }
1379                else
1380                {
1381                    last_entry.next       = r_read_next_ptr.read();
1382                }
1383                m_heap.write(r_read_ptr.read(),last_entry);
1384                r_read_fsm = READ_RSP;
1385            }
1386            else
1387            {
1388                std::cout << "VCI_MEM_CACHE ERROR " << name()
1389                          << " READ_HEAP_LAST state" << std::endl;
1390                std::cout << "Bad HEAP allocation" << std::endl;
1391                exit(0);
[2]1392            }
[184]1393            break;
[2]1394        }
1395        //////////////
[184]1396        case READ_RSP:          //  request the TGT_RSP FSM to return data
[2]1397        {
[184]1398            if( !r_read_to_tgt_rsp_req )
1399            {   
1400                for ( size_t i=0 ; i<m_words ; i++ )  r_read_to_tgt_rsp_data[i] = r_read_data[i];
1401                r_read_to_tgt_rsp_word   = m_x[(vci_addr_t)m_cmd_read_addr_fifo.read()];
1402                r_read_to_tgt_rsp_length = m_cmd_read_length_fifo.read();
1403                r_read_to_tgt_rsp_srcid  = m_cmd_read_srcid_fifo.read();
1404                r_read_to_tgt_rsp_trdid  = m_cmd_read_trdid_fifo.read();
1405                r_read_to_tgt_rsp_pktid  = m_cmd_read_pktid_fifo.read();
1406                cmd_read_fifo_get        = true;
1407                r_read_to_tgt_rsp_req    = true;
1408                r_read_fsm               = READ_IDLE; 
1409
1410#if DEBUG_MEMC_READ
1411if( m_debug_read_fsm )
1412{
1413    std::cout << "  <MEMC.READ_RSP> Request the TGT_RSP FSM to return data:"
1414              << " rsrcid = " << std::hex << m_cmd_read_srcid_fifo.read()
1415              << " / address = " << m_cmd_read_addr_fifo.read()
1416              << " / nwords = " << std::dec << m_cmd_read_length_fifo.read() << std::endl;
1417}
1418#endif
[2]1419            }
[184]1420            break;
[2]1421        }
1422        ///////////////////
[184]1423        case READ_TRT_LOCK:     // read miss : check the Transaction Table
[2]1424        {
[184]1425            if ( r_alloc_trt_fsm.read() == ALLOC_TRT_READ )
1426            {
1427                size_t      index     = 0;
1428                vci_addr_t  addr      = (vci_addr_t)m_cmd_read_addr_fifo.read();
1429                bool        hit_read  = m_transaction_tab.hit_read(m_nline[addr], index);
1430                bool        hit_write = m_transaction_tab.hit_write(m_nline[addr]);
1431                bool        wok       = !m_transaction_tab.full(index);
1432
1433                if( hit_read || !wok || hit_write )  // missing line already requested or no space
1434                {
1435                    if(!wok)                    m_cpt_trt_full++;
1436                    if(hit_read || hit_write)   m_cpt_trt_rb++;
1437                    r_read_fsm = READ_IDLE;
1438                }
1439                else                                // missing line is requested to the XRAM
1440                {
1441                    m_cpt_read_miss++;
1442                    r_read_trt_index = index;
1443                    r_read_fsm       = READ_TRT_SET;
1444                }
1445
1446#if DEBUG_MEMC_READ
1447if( m_debug_read_fsm )
1448{
1449    std::cout << "  <MEMC.READ_TRT_LOCK> Check TRT:"
1450              << " hit_read = " << hit_read
1451              << " / hit_write = " << hit_write
1452              << " / full = " << !wok << std::endl;
[57]1453}
[2]1454#endif
1455            }
[184]1456            break;
[2]1457        }
1458        //////////////////
[184]1459        case READ_TRT_SET:      // register get transaction in TRT
[2]1460        {
[184]1461            if ( r_alloc_trt_fsm.read() == ALLOC_TRT_READ )
1462            {
1463                m_transaction_tab.set(r_read_trt_index.read(),
1464                                      true,
1465                                      m_nline[(vci_addr_t)(m_cmd_read_addr_fifo.read())],
1466                                      m_cmd_read_srcid_fifo.read(),
1467                                      m_cmd_read_trdid_fifo.read(),
1468                                      m_cmd_read_pktid_fifo.read(),
1469                                      true,
1470                                      m_cmd_read_length_fifo.read(),
1471                                      m_x[(vci_addr_t)(m_cmd_read_addr_fifo.read())],
1472                                      std::vector<be_t>(m_words,0),
1473                                      std::vector<data_t>(m_words,0));
1474#if DEBUG_MEMC_READ
1475if( m_debug_read_fsm )
1476{
1477    std::cout << "  <MEMC.READ_TRT_SET> Write in Transaction Table: " << std::hex
1478              << " address = " << m_cmd_read_addr_fifo.read()
1479              << " / srcid = " << m_cmd_read_srcid_fifo.read() << std::endl;
[57]1480}
[2]1481#endif
[184]1482                r_read_fsm = READ_TRT_REQ;
1483            }
1484            break;
1485        }
1486        //////////////////
1487        case READ_TRT_REQ:              // consume the read request in the FIFO,
1488                                                // and send it to the ixr_cmd_fsm
1489        {       
1490            if( not r_read_to_ixr_cmd_req )
1491            {
1492                cmd_read_fifo_get           = true;
1493                r_read_to_ixr_cmd_req   = true;
1494                r_read_to_ixr_cmd_nline = m_nline[(vci_addr_t)(m_cmd_read_addr_fifo.read())];
1495                r_read_to_ixr_cmd_trdid = r_read_trt_index.read();
1496                r_read_fsm                  = READ_IDLE;
[2]1497
[184]1498#if DEBUG_MEMC_READ
1499if( m_debug_read_fsm )
1500{
1501    std::cout << "  <MEMC.READ_TRT_REQ> Request GET transaction for address "
1502              << m_cmd_read_addr_fifo.read() << std::endl;
1503}
1504#endif
1505            }
1506            break;
[2]1507        }
1508    } // end switch read_fsm
1509
1510    ///////////////////////////////////////////////////////////////////////////////////
1511    //          WRITE FSM
1512    ///////////////////////////////////////////////////////////////////////////////////
1513    // The WRITE FSM handles the write bursts sent by the processors.
1514    // All addresses in a burst must be in the same cache line.
1515    // A complete write burst is consumed in the FIFO & copied to a local buffer.
1516    // Then the FSM takes the lock protecting the cache directory, to check
1517    // if the line is in the cache.
1518    //
1519    // - In case of HIT, the cache is updated.
1520    //   If there is no other copy, an acknowledge response is immediately
1521    //   returned to the writing processor.
[184]1522    //   If the data is cached by other processors, a coherence transaction must
1523    //   be launched:
1524    //   It is a multicast update if the line is not in counter mode, and the processor
1525    //   takes the lock protecting the Update Table (UPT) to register this transaction.
1526    //   It is a broadcast invalidate if the line is in counter mode.
1527    //   If the UPT is full, it releases the lock(s) and retry. Then, it sends
[2]1528    //   a multi-update request to all owners of the line (but the writer),
[200]1529    //   through the INIT_CMD FSM. In case of coherence transaction, the WRITE FSM
[2]1530    //   does not respond to the writing processor, as this response will be sent by
1531    //   the INIT_RSP FSM when all update responses have been received.
1532    //
1533    // - In case of MISS, the WRITE FSM takes the lock protecting the transaction
1534    //   table (TRT). If a read transaction to the XRAM for this line already exists,
1535    //   it writes in the TRT (write buffer). Otherwise, if a TRT entry is free,
1536    //   the WRITE FSM register a new transaction in TRT, and sends a read line request
1537    //   to the XRAM. If the TRT is full, it releases the lock, and waits.
1538    //   Finally, the WRITE FSM returns an aknowledge response to the writing processor.
1539    /////////////////////////////////////////////////////////////////////////////////////
1540
[184]1541    switch ( r_write_fsm.read() )
1542    {
1543        ////////////////
1544        case WRITE_IDLE:        // copy first word of a write burst in local buffer     
[2]1545        {
[184]1546            if ( m_cmd_write_addr_fifo.rok() )
1547            {
1548                m_cpt_write++;
1549                m_cpt_write_cells++;
[140]1550
[184]1551                // consume a word in the FIFO & write it in the local buffer
1552                cmd_write_fifo_get      = true;
1553                size_t index            = m_x[(vci_addr_t)(m_cmd_write_addr_fifo.read())];
[2]1554
[184]1555                r_write_address         = (addr_t)(m_cmd_write_addr_fifo.read());
1556                r_write_word_index      = index;
1557                r_write_word_count      = 1;
1558                r_write_data[index]     = m_cmd_write_data_fifo.read();
1559                r_write_srcid           = m_cmd_write_srcid_fifo.read();
1560                r_write_trdid           = m_cmd_write_trdid_fifo.read();
1561                r_write_pktid           = m_cmd_write_pktid_fifo.read();
1562
1563                // initialize the be field for all words
1564                for ( size_t i=0 ; i<m_words ; i++ )
1565                {
1566                    if ( i == index ) r_write_be[i] = m_cmd_write_be_fifo.read();
1567                    else              r_write_be[i] = 0x0;
1568                }
1569
1570                if( !((m_cmd_write_be_fifo.read() == 0x0)||(m_cmd_write_be_fifo.read() == 0xF)) )
1571                    r_write_byte = true;
1572                else   
1573                    r_write_byte = false;
1574
1575                if( m_cmd_write_eop_fifo.read() )  r_write_fsm = WRITE_DIR_LOCK;
1576                else                               r_write_fsm = WRITE_NEXT;
1577
1578#if DEBUG_MEMC_WRITE
1579if( m_debug_write_fsm )
1580{
1581    std::cout << "  <MEMC.WRITE_IDLE> Write request "
1582              << " srcid = " << std::hex << m_cmd_write_srcid_fifo.read()
1583              << " / address = " << m_cmd_write_addr_fifo.read()
1584              << " / data = " << m_cmd_write_data_fifo.read() << std::endl;
1585}
1586#endif
[2]1587            }
[184]1588            break;
[2]1589        }
1590        ////////////////
[184]1591        case WRITE_NEXT:        // copy next word of a write burst in local buffer
[2]1592        {
[184]1593            if ( m_cmd_write_addr_fifo.rok() )
1594            {
[2]1595
[184]1596#if DEBUG_MEMC_WRITE
1597if( m_debug_write_fsm )
1598{
1599    std::cout << "  <MEMC.WRITE_NEXT> Write another word in local buffer" << std::endl;
1600}
1601#endif
1602                m_cpt_write_cells++;
1603
1604                // check that the next word is in the same cache line
1605                if ( (m_nline[(vci_addr_t)(r_write_address.read())] !=
1606                      m_nline[(vci_addr_t)(m_cmd_write_addr_fifo.read())]) )
1607                {
1608                    std::cout << "VCI_MEM_CACHE ERROR " << name() << " WRITE_NEXT state" << std::endl;
1609                    std::cout << "all words in a write burst must be in same cache line" << std::endl;
1610                    exit(0);
1611                }
1612
1613                // consume a word in the FIFO & write it in the local buffer
1614                cmd_write_fifo_get=true;
1615                size_t index            = r_write_word_index.read() + r_write_word_count.read();
1616
1617                r_write_be[index]       = m_cmd_write_be_fifo.read();
1618                r_write_data[index]     = m_cmd_write_data_fifo.read();
1619                r_write_word_count      = r_write_word_count.read() + 1;
1620
1621                if( !((m_cmd_write_be_fifo.read() == 0x0)||(m_cmd_write_be_fifo.read() == 0xF)) )
1622                    r_write_byte = true;
1623
1624                if ( m_cmd_write_eop_fifo.read() )  r_write_fsm = WRITE_DIR_LOCK;
1625            }
1626            break;
[2]1627        }
1628        ////////////////////
[184]1629        case WRITE_DIR_LOCK:    // access directory to check hit/miss
[2]1630        {
[184]1631            if ( r_alloc_dir_fsm.read() == ALLOC_DIR_WRITE )
1632            {
1633                size_t  way = 0;
1634                DirectoryEntry entry(m_cache_directory.read(r_write_address.read(), way));
[2]1635
[184]1636                if ( entry.valid ) // hit
1637                {       
1638                    // copy directory entry in local buffer in case of hit
1639                    r_write_is_cnt     = entry.is_cnt;
1640                    r_write_lock       = entry.lock;
1641                    r_write_tag        = entry.tag;
1642                    r_write_copy       = entry.owner.srcid;
[140]1643#if L1_MULTI_CACHE
[184]1644                    r_write_copy_cache = entry.owner.cache_id;
[140]1645#endif
[184]1646                    r_write_copy_inst  = entry.owner.inst;
1647                    r_write_count      = entry.count;
1648                    r_write_ptr        = entry.ptr;
1649                    r_write_way        = way;
1650
1651                    if( entry.is_cnt && entry.count )
1652                    {
[200]1653                        r_write_fsm      = WRITE_DIR_READ;
[184]1654                    }
1655                    else
1656                    {
[200]1657                        if (r_write_byte.read())        r_write_fsm = WRITE_DIR_READ;
[184]1658                        else                                    r_write_fsm = WRITE_DIR_HIT;
1659                    }
1660                }
1661                else    // miss
1662                {
[200]1663                    r_write_fsm = WRITE_MISS_TRT_LOCK;
[184]1664                }
1665
1666#if DEBUG_MEMC_WRITE
1667if( m_debug_write_fsm )
1668{
1669    std::cout << "  <MEMC.WRITE_DIR_LOCK> Check the directory: "
[200]1670              << " address = " << std::hex << r_write_address.read()
[184]1671              << " hit = " << entry.valid
1672              << " count = " << std::dec << entry.count
1673              << " is_cnt = " << entry.is_cnt << std::endl;
1674}
1675#endif
[2]1676            }
[184]1677            break;
[2]1678        }
[200]1679        ////////////////////
1680        case WRITE_DIR_READ:    // read the cache and complete the buffer when be!=0xF
[2]1681        {
[184]1682            // update local buffer
1683            size_t set  = m_y[(vci_addr_t)(r_write_address.read())];
1684            size_t way  = r_write_way.read();
1685            for(size_t i=0 ; i<m_words ; i++)
1686            {
1687                data_t mask = 0;
1688                if  (r_write_be[i].read() & 0x1) mask = mask | 0x000000FF;
1689                if  (r_write_be[i].read() & 0x2) mask = mask | 0x0000FF00;
1690                if  (r_write_be[i].read() & 0x4) mask = mask | 0x00FF0000;
1691                if  (r_write_be[i].read() & 0x8) mask = mask | 0xFF000000;
[2]1692
[184]1693                // complete only if mask is not null (for energy consumption)
1694                if ( r_write_be[i].read() || r_write_is_cnt.read() )
1695                {
1696                    r_write_data[i]  = (r_write_data[i].read() & mask) |
1697                                           (m_cache_data[way][set][i] & ~mask);
1698                }
1699            } // end for
1700
1701            // test if a coherence broadcast is required
[200]1702            if( r_write_is_cnt.read() && r_write_count.read() ) r_write_fsm = WRITE_BC_TRT_LOCK;
1703            else                                                                        r_write_fsm = WRITE_DIR_HIT;
[184]1704
1705#if DEBUG_MEMC_WRITE
1706if( m_debug_write_fsm )
1707{
1708    if( r_write_is_cnt.read() && r_write_count.read() )
1709    {
[200]1710        std::cout << "  <MEMC.WRITE_DIR_READ> Read the cache to complete local buffer /"
[184]1711                  << " coherence broadcast required" << std::endl;
1712    }
1713    else
1714    {
[200]1715        std::cout << "  <MEMC.WRITE_DIR_READ> Read the cache to complete local buffer"
[184]1716                  << std::endl;
1717    }
1718}
1719#endif
1720            break;
[2]1721        }
1722        ///////////////////
[200]1723        case WRITE_DIR_HIT:        // update the cache directory
[2]1724        {
[184]1725            // update directory with Dirty bit
1726            DirectoryEntry entry;
1727            entry.valid          = true;
1728            entry.dirty          = true;
1729            entry.tag            = r_write_tag.read();
1730            entry.is_cnt         = r_write_is_cnt.read();
1731            entry.lock           = r_write_lock.read();
1732            entry.owner.srcid    = r_write_copy.read();
[140]1733#if L1_MULTI_CACHE
[184]1734            entry.owner.cache_id = r_write_copy_cache.read();
[140]1735#endif
[184]1736            entry.owner.inst     = r_write_copy_inst.read();
1737            entry.count          = r_write_count.read();
1738            entry.ptr            = r_write_ptr.read();
1739            size_t set           = m_y[(vci_addr_t)(r_write_address.read())];
1740            size_t way           = r_write_way.read();
[2]1741
[184]1742            // update directory
1743            m_cache_directory.write(set, way, entry);
1744
[200]1745            // owner is true when the  the first registered copy is the writer itself
[184]1746            bool owner = (((r_write_copy.read() == r_write_srcid.read())
[140]1747#if L1_MULTI_CACHE
1748                         and (r_write_copy_cache.read()==r_write_pktid.read())
1749#endif
1750                         ) and not r_write_copy_inst.read());
1751
[184]1752            // no_update is true when there is no need for coherence transaction
1753            bool no_update = (r_write_count.read()==0) || ( owner && (r_write_count.read()==1));
[2]1754
[200]1755            // write data in the cache if no coherence transaction
[184]1756            if( no_update )
1757            {
1758                for(size_t i=0 ; i<m_words ; i++)
1759                {
1760                    if  ( r_write_be[i].read() ) m_cache_data[way][set][i]  = r_write_data[i].read();
1761                }
1762            }
[2]1763
[184]1764            if ( owner )   r_write_count = r_write_count.read() - 1;
[2]1765
[184]1766            if ( no_update )      // Write transaction completed
1767            {
1768                r_write_fsm = WRITE_RSP;
1769            }
1770            else          // coherence update required       
1771            {
1772                if( !r_write_to_init_cmd_multi_req.read() &&
1773                   !r_write_to_init_cmd_brdcast_req.read()  )   r_write_fsm = WRITE_UPT_LOCK;
[200]1774                else                                                                r_write_fsm = WRITE_WAIT;
[184]1775            }
1776
1777#if DEBUG_MEMC_WRITE
1778if( m_debug_write_fsm )
1779{
1780    if ( no_update )
1781    {
1782        std::cout << "  <MEMC.WRITE_DIR_HIT> Write into cache / No coherence transaction"
1783                  << std::endl;
1784    }
1785    else
1786    {
1787        std::cout << "  <MEMC.WRITE_DIR_HIT> Coherence update required:"
1788                  << " is_cnt = " << r_write_is_cnt.read()
1789                  << " count = " << std::dec << r_write_count.read()
1790                  << std::endl;
1791    }
1792}
1793#endif
1794            break;
[2]1795        }
[200]1796        ////////////////////
[184]1797        case WRITE_UPT_LOCK:    // Try to register the update request in UPT
[2]1798        {
[184]1799            if ( r_alloc_upt_fsm.read() == ALLOC_UPT_WRITE )
1800            {
1801                bool        wok        = false;
1802                size_t      index      = 0;
1803                size_t      srcid      = r_write_srcid.read();
1804                size_t      trdid      = r_write_trdid.read();
1805                size_t      pktid      = r_write_pktid.read();
1806                addr_t      nline      = m_nline[(vci_addr_t)(r_write_address.read())];
1807                size_t      nb_copies  = r_write_count.read();
1808                size_t      set        = m_y[(vci_addr_t)(r_write_address.read())];
1809                size_t      way        = r_write_way.read();
[2]1810
[184]1811                wok = m_update_tab.set(true,    // it's an update transaction
1812                                      false,    // it's not a broadcast
1813                                      true,     // it needs a response
1814                                      srcid,
1815                                      trdid,
1816                                      pktid,
1817                                      nline,
1818                                      nb_copies,
1819                                      index);
1820                if ( wok )    // write data in cache
1821                {
1822                    for(size_t i=0 ; i<m_words ; i++)
1823                    {
1824                        if ( r_write_be[i].read() ) m_cache_data[way][set][i] = r_write_data[i].read();
1825                    }
1826                }
[2]1827
[184]1828#if DEBUG_MEMC_WRITE
1829if( m_debug_write_fsm )
1830{
1831    if ( wok )
1832    {
1833        std::cout << "  <MEMC.WRITE_UPT_LOCK> Register the multicast update in UPT / "
1834                  << " nb_copies = " << r_write_count.read() << std::endl;
1835    }
[57]1836}
[2]1837#endif
[184]1838                r_write_upt_index = index;
[200]1839                //  releases the lock protecting UPT and the DIR if no entry...
1840                if ( wok ) r_write_fsm = WRITE_UPT_HEAP_LOCK;
[184]1841                else       r_write_fsm = WRITE_WAIT;
1842            }
1843            break;
[2]1844        }
[184]1845        /////////////////////
[200]1846        case WRITE_UPT_HEAP_LOCK:   // get access to heap
[2]1847        {
[184]1848            if( r_alloc_heap_fsm.read() == ALLOC_HEAP_WRITE )
1849            {
1850
1851#if DEBUG_MEMC_WRITE
1852if( m_debug_write_fsm )
1853{
[200]1854    std::cout << "  <MEMC.WRITE_UPT_HEAP_LOCK> Get acces to the HEAP" << std::endl;
[184]1855}
1856#endif
1857                r_write_fsm = WRITE_UPT_REQ;
1858            }
1859            break;
[2]1860        }
1861        //////////////////
[200]1862        case WRITE_UPT_REQ:     //  prepare the request to INIT_CMD FSM
1863                                //  and write the first srcid in the FIFO
1864                                //  send the request if only one copy
[2]1865        {
[184]1866            if( !r_write_to_init_cmd_multi_req.read() &&
[200]1867                !r_write_to_init_cmd_brdcast_req.read()  )  // no pending coherence request
[184]1868            {
1869                r_write_to_init_cmd_brdcast_req  = false;
1870                r_write_to_init_cmd_trdid        = r_write_upt_index.read();
1871                r_write_to_init_cmd_nline        = m_nline[(vci_addr_t)(r_write_address.read())];
1872                r_write_to_init_cmd_index        = r_write_word_index.read();
1873                r_write_to_init_cmd_count        = r_write_word_count.read();
1874
[200]1875                for(size_t i=0; i<m_words ; i++) r_write_to_init_cmd_be[i]=r_write_be[i].read();
[184]1876
1877                size_t min = r_write_word_index.read();
1878                size_t max = r_write_word_index.read() + r_write_word_count.read();
[200]1879                for (size_t i=min ; i<max ; i++) r_write_to_init_cmd_data[i] = r_write_data[i];
[2]1880           
[184]1881                if( (r_write_copy.read() != r_write_srcid.read()) or
[140]1882#if L1_MULTI_CACHE
[184]1883                    (r_write_copy_cache.read() != r_write_pktid.read()) or
[140]1884#endif
[184]1885                    r_write_copy_inst.read() )
1886                {
[200]1887                    // put the first srcid in the fifo
[184]1888                    write_to_init_cmd_fifo_put     = true;
1889                    write_to_init_cmd_fifo_inst    = r_write_copy_inst.read();
1890                    write_to_init_cmd_fifo_srcid   = r_write_copy.read();
[140]1891#if L1_MULTI_CACHE
[184]1892                    write_to_init_cmd_fifo_cache_id= r_write_copy_cache.read();
[140]1893#endif
[184]1894                    if(r_write_count.read() == 1)
1895                    {
1896                        r_write_fsm = WRITE_IDLE;
1897                        r_write_to_init_cmd_multi_req = true;
1898                    }
1899                    else
1900                    {
[200]1901                        r_write_fsm = WRITE_UPT_NEXT;
1902                        r_write_to_dec = false;
1903
[184]1904                    }
1905                }
1906                else
1907                {
[200]1908                    r_write_fsm = WRITE_UPT_NEXT;
1909                    r_write_to_dec = false;
[184]1910                }
[2]1911            }
[184]1912            break;
[2]1913        }
[200]1914        ///////////////////
1915        case WRITE_UPT_NEXT:    // continue the multi-update request to INIT_CMD fsm
1916                                // when there is copies in the heap.
1917                                // if one copy in the heap is the writer itself
1918                                // the corresponding SRCID should not be written in the fifo,
1919                                // but the UPT counter must be decremented.
1920                                // As this decrement is done in the WRITE_UPT_DEC state,
1921                                // after the last copy has been found, the decrement request
1922                                // must be  registered in the r_write_to_dec flip-flop.
[2]1923        {
[184]1924            HeapEntry entry = m_heap.read(r_write_ptr.read());
[140]1925         
[200]1926            bool dec_upt_counter; // = r_write_to_dec.read();
1927
[184]1928            if( (entry.owner.srcid != r_write_srcid.read()) or
[140]1929#if L1_MULTI_CACHE
[184]1930                (entry.owner.cache_id != r_write_pktid.read()) or
[140]1931#endif
[200]1932                entry.owner.inst)   // put te next srcid in the fifo
[184]1933            {
[200]1934                dec_upt_counter                 = false;
1935                write_to_init_cmd_fifo_put      = true;
1936                write_to_init_cmd_fifo_inst     = entry.owner.inst;
1937                write_to_init_cmd_fifo_srcid    = entry.owner.srcid;
1938#if L1_MULTI_CACHE
1939                write_to_init_cmd_fifo_cache_id = entry.owner.cache_id;
1940#endif
[184]1941            }
[200]1942            else                    // the UPT counter must be decremented
[184]1943            {
1944                dec_upt_counter = true;
1945            }
[2]1946
[200]1947            // register the possible UPT decrement request
1948            r_write_to_dec = dec_upt_counter or r_write_to_dec.read();
1949
1950            if( not m_write_to_init_cmd_inst_fifo.wok() )
[184]1951            {
[200]1952                std::cout << "VCI_MEM_CACHE ERROR " << name() << " WRITE_UPT_NEXT state" << std::endl
1953                          << "The write_to_cmd_write_fifo should not be full" << std::endl
1954                          << "as the depth should be larger than the max number of copies" << std::endl;
1955                exit(0);
1956            }
1957
1958            r_write_ptr = entry.next;
1959
1960            if( entry.next == r_write_ptr.read() )  // last copy
1961            {
1962                r_write_to_init_cmd_multi_req = true;
1963                if( r_write_to_dec.read() or dec_upt_counter)   r_write_fsm = WRITE_UPT_DEC;
1964                else                                                r_write_fsm = WRITE_IDLE;
[184]1965            }
1966            break;
[2]1967        }
1968        //////////////////
[200]1969        case WRITE_UPT_DEC:     // If the initial writer has a copy, it should not
1970                                // receive an update request, but the counter in the
1971                                // update table must be decremented by the INIT_RSP FSM.
[2]1972        {
[184]1973            if ( !r_write_to_init_rsp_req.read() )
1974            {
1975                r_write_to_init_rsp_req = true;
1976                r_write_to_init_rsp_upt_index = r_write_upt_index.read();
1977                r_write_fsm = WRITE_IDLE;
1978            }
1979            break;
[2]1980        }
1981        ///////////////
[184]1982        case WRITE_RSP:         // Post a request to TGT_RSP FSM to acknowledge the write
[2]1983        {
[184]1984            if ( !r_write_to_tgt_rsp_req.read() )
1985            {
[140]1986
[184]1987#if DEBUG_MEMC_WRITE
1988if( m_debug_write_fsm )
1989{
1990    std::cout << "  <MEMC.WRITE_RSP> Post a request to TGT_RSP FSM: rsrcid = "
1991              << std::hex << r_write_srcid.read() << std:: endl;
1992}
1993#endif
1994                r_write_to_tgt_rsp_req   = true;
1995                r_write_to_tgt_rsp_srcid = r_write_srcid.read();
1996                r_write_to_tgt_rsp_trdid = r_write_trdid.read();
1997                r_write_to_tgt_rsp_pktid = r_write_pktid.read();
[200]1998                r_write_fsm              = WRITE_IDLE;
[184]1999            }
2000            break;
[2]2001        }
[200]2002        /////////////////////////
2003        case WRITE_MISS_TRT_LOCK:       // Miss : check Transaction Table
[2]2004        {
[184]2005            if ( r_alloc_trt_fsm.read() == ALLOC_TRT_WRITE )
2006            {
2007
2008#if DEBUG_MEMC_WRITE
2009if( m_debug_write_fsm )
2010{
[200]2011    std::cout << "  <MEMC.WRITE_MISS_TRT_LOCK> Check the TRT" << std::endl;
[57]2012}
[2]2013#endif
[184]2014                size_t          hit_index = 0;
2015                size_t          wok_index = 0;
2016                vci_addr_t      addr      = (vci_addr_t)r_write_address.read();
2017                bool            hit_read  = m_transaction_tab.hit_read(m_nline[addr], hit_index);
2018                bool            hit_write = m_transaction_tab.hit_write(m_nline[addr]);
2019                bool            wok       = !m_transaction_tab.full(wok_index);
2020
2021                if ( hit_read )         // register the modified data in TRT
2022                {
2023                    r_write_trt_index = hit_index;
[200]2024                    r_write_fsm       = WRITE_MISS_TRT_DATA;
[184]2025                    m_cpt_write_miss++;
2026                }
2027                else if ( wok && !hit_write )   // set a new entry in TRT
2028                {
2029                    r_write_trt_index = wok_index;
[200]2030                    r_write_fsm       = WRITE_MISS_TRT_SET;
[184]2031                    m_cpt_write_miss++;
2032                }
2033                else            // wait an empty entry in TRT
2034                {
2035                    r_write_fsm       = WRITE_WAIT;
2036                    m_cpt_trt_full++;
2037                }
[2]2038            }
[184]2039            break;
[2]2040        }
[184]2041        ////////////////
2042        case WRITE_WAIT:        // release the locks protecting the shared ressources
[2]2043        {
[184]2044
2045#if DEBUG_MEMC_WRITE
2046if( m_debug_write_fsm )
2047{
2048    std::cout << "  <MEMC.WRITE_WAIT> Releases the locks before retry" << std::endl;
2049}
2050#endif
2051            r_write_fsm = WRITE_DIR_LOCK;
2052            break;
[2]2053        }
[200]2054        ////////////////////////
2055        case WRITE_MISS_TRT_SET:        // register a new transaction in TRT (Write Buffer)
[2]2056        { 
[184]2057            if ( r_alloc_trt_fsm.read() == ALLOC_TRT_WRITE )
[2]2058            {
[184]2059                std::vector<be_t>       be_vector;
2060                std::vector<data_t> data_vector;
2061                be_vector.clear();
2062                data_vector.clear();
2063                for ( size_t i=0; i<m_words; i++ )
2064                {
2065                    be_vector.push_back(r_write_be[i]);
2066                    data_vector.push_back(r_write_data[i]);
2067                }
2068                m_transaction_tab.set(r_write_trt_index.read(),
2069                                      true,                     // read request to XRAM
2070                                      m_nline[(vci_addr_t)(r_write_address.read())],
2071                                      r_write_srcid.read(),
2072                                      r_write_trdid.read(),
2073                                      r_write_pktid.read(),
2074                                      false,                    // not a processor read
2075                                      0,                        // not a single word
2076                                      0,                        // word index
2077                                      be_vector,
2078                                      data_vector);
[200]2079                r_write_fsm = WRITE_MISS_XRAM_REQ;
[184]2080
2081#if DEBUG_MEMC_WRITE
2082if( m_debug_write_fsm )
2083{
[200]2084    std::cout << "  <MEMC.WRITE_MISS_TRT_SET> Set a new entry in TRT" << std::endl;
[57]2085}
[2]2086#endif
[184]2087            }
2088            break;
[2]2089        } 
[200]2090        /////////////////////////
2091        case WRITE_MISS_TRT_DATA:       // update an entry in TRT (used as a Write Buffer)
[2]2092        {
[184]2093            if ( r_alloc_trt_fsm.read() == ALLOC_TRT_WRITE )
2094            {
2095                std::vector<be_t> be_vector;
2096                std::vector<data_t> data_vector;
2097                be_vector.clear();
2098                data_vector.clear();
2099                for ( size_t i=0; i<m_words; i++ )
2100                {
2101                    be_vector.push_back(r_write_be[i]);
2102                    data_vector.push_back(r_write_data[i]);
2103                }
2104                m_transaction_tab.write_data_mask(r_write_trt_index.read(),
2105                                                  be_vector,
2106                                                  data_vector);
2107                r_write_fsm = WRITE_RSP;
2108
2109#if DEBUG_MEMC_WRITE
2110if( m_debug_write_fsm )
2111{
[200]2112    std::cout << "  <MEMC.WRITE_MISS_TRT_DATA> Modify an existing entry in TRT" << std::endl;
[184]2113    m_transaction_tab.print( r_write_trt_index.read() );
[57]2114}
[2]2115#endif
[184]2116            }
2117            break;
[2]2118        }
[200]2119        /////////////////////////
2120        case WRITE_MISS_XRAM_REQ:       // send a GET request to IXR_CMD FSM
[2]2121        { 
[184]2122            if ( !r_write_to_ixr_cmd_req )
2123            {
2124                r_write_to_ixr_cmd_req   = true;
2125                r_write_to_ixr_cmd_write = false;
2126                r_write_to_ixr_cmd_nline = m_nline[(vci_addr_t)(r_write_address.read())];
2127                r_write_to_ixr_cmd_trdid = r_write_trt_index.read();
2128                r_write_fsm              = WRITE_RSP;
[2]2129
[184]2130#if DEBUG_MEMC_WRITE
2131if( m_debug_write_fsm )
2132{
[200]2133    std::cout << "  <MEMC.WRITE_MISS_XRAM_REQ> Post a GET request to the IXR_CMD FSM" << std::endl;
[184]2134}
2135#endif
2136            }
2137            break;
[2]2138        }
[200]2139        ///////////////////////
2140        case WRITE_BC_TRT_LOCK:     // Check TRT not full
[2]2141        {
[184]2142            if ( r_alloc_trt_fsm.read() == ALLOC_TRT_WRITE )
2143            {
2144                size_t wok_index = 0;
2145                bool wok = !m_transaction_tab.full( wok_index );
2146                if ( wok )      // set a new entry in TRT
2147                {
2148                    r_write_trt_index = wok_index;
[200]2149                    r_write_fsm       = WRITE_BC_UPT_LOCK;
[184]2150                }
2151                else    // wait an empty entry in TRT
2152                {
2153                    r_write_fsm       = WRITE_WAIT;
2154                }
2155
2156#if DEBUG_MEMC_WRITE
2157if( m_debug_write_fsm )
2158{
[200]2159    std::cout << "  <MEMC.WRITE_BC_TRT_LOCK> Check TRT : wok = "
2160              << wok << " / index = " << wok_index << std::endl;
[184]2161}
2162#endif
[2]2163            }
[184]2164            break;
[2]2165        }
[184]2166        //////////////////////
[200]2167        case WRITE_BC_UPT_LOCK:      // register BC transaction in UPT
[2]2168        {
[184]2169            if ( r_alloc_upt_fsm.read() == ALLOC_UPT_WRITE )
2170            {
2171                bool        wok       = false;
2172                size_t      index     = 0;
2173                size_t      srcid     = r_write_srcid.read();
2174                size_t      trdid     = r_write_trdid.read();
2175                size_t      pktid     = r_write_pktid.read();
2176                addr_t      nline     = m_nline[(vci_addr_t)(r_write_address.read())];
2177                size_t      nb_copies = r_write_count.read();
[2]2178
[184]2179                wok =m_update_tab.set(false,    // it's an inval transaction
2180                                      true,     // it's a broadcast
2181                                      true,     // it needs a response
2182                                      srcid,
2183                                      trdid,
2184                                      pktid,
2185                                      nline,
2186                                      nb_copies,
2187                                      index);
2188
2189#if DEBUG_MEMC_WRITE
2190if( m_debug_write_fsm )
2191{
2192    if ( wok )
2193    {
[200]2194        std::cout << "  <MEMC.WRITE_BC_UPT_LOCK> Register the broadcast inval in UPT / "
[184]2195                  << " nb_copies = " << r_write_count.read() << std::endl;
2196    }
[57]2197}
[2]2198#endif
[184]2199                r_write_upt_index = index;
[2]2200
[200]2201                if ( wok ) r_write_fsm = WRITE_BC_DIR_INVAL;
[184]2202                else       r_write_fsm = WRITE_WAIT;
2203            }
2204            break;
[2]2205        }
[200]2206        ////////////////////////
2207        case WRITE_BC_DIR_INVAL:        // Register a put transaction to XRAM in TRT
[184]2208                                // and invalidate the line in directory
[2]2209        {
[184]2210            if ( (r_alloc_trt_fsm.read() != ALLOC_TRT_WRITE ) ||
2211                 (r_alloc_upt_fsm.read() != ALLOC_UPT_WRITE ) ||
2212                 (r_alloc_dir_fsm.read() != ALLOC_DIR_WRITE ) )
2213            {
[200]2214                std::cout << "VCI_MEM_CACHE ERROR " << name() << " WRITE_BC_DIR_INVAL state" << std::endl;
[184]2215                std::cout << "bad TRT, DIR, or UPT allocation" << std::endl;
2216                exit(0);
2217            }
2218
2219            // register a write request to XRAM in TRT
[2]2220            m_transaction_tab.set(r_write_trt_index.read(),
[184]2221                                  false,                // write request to XRAM
2222                                  m_nline[(vci_addr_t)(r_write_address.read())],
2223                                  0,
2224                                  0,
2225                                  0,
2226                                  false,                // not a processor read
2227                                  0,                    // not a single word
2228                                  0,                    // word index
2229                                  std::vector<be_t>(m_words,0),
2230                                  std::vector<data_t>(m_words,0));
[2]2231            // invalidate directory entry
2232            DirectoryEntry entry;
2233            entry.valid         = false;
2234            entry.dirty         = false;
2235            entry.tag           = 0;
2236            entry.is_cnt        = false;
2237            entry.lock          = false;
2238            entry.owner.srcid   = 0;
[140]2239#if L1_MULTI_CACHE
2240            entry.owner.cache_id= 0;
2241#endif
[2]2242            entry.owner.inst    = false;
2243            entry.ptr           = 0;
2244            entry.count         = 0;
2245            size_t set          = m_y[(vci_addr_t)(r_write_address.read())];
2246            size_t way          = r_write_way.read();
[184]2247
[2]2248            m_cache_directory.write(set, way, entry);
2249
[184]2250#if DEBUG_MEMC_WRITE
2251if( m_debug_write_fsm )
2252{
[200]2253    std::cout << "  <MEMC.WRITE_BC_DIR_INVAL> Invalidate the directory entry: @ = "
[184]2254              << r_write_address.read() << " / register the put transaction in TRT:" << std::endl;
2255}
2256#endif
[200]2257            r_write_fsm = WRITE_BC_CC_SEND;
[2]2258            break;
2259        }
[200]2260        //////////////////////
2261        case WRITE_BC_CC_SEND:    // Post a coherence broadcast request to INIT_CMD FSM
[2]2262        {
[184]2263            if ( !r_write_to_init_cmd_multi_req.read() && !r_write_to_init_cmd_brdcast_req.read() )
2264            {
2265                r_write_to_init_cmd_multi_req   = false;
2266                r_write_to_init_cmd_brdcast_req = true;
2267                r_write_to_init_cmd_trdid       = r_write_upt_index.read();
2268                r_write_to_init_cmd_nline       = m_nline[(vci_addr_t)(r_write_address.read())];
2269                r_write_to_init_cmd_index       = 0;
2270                r_write_to_init_cmd_count       = 0;
[2]2271
[184]2272                for(size_t i=0; i<m_words ; i++)
2273                {
2274                    r_write_to_init_cmd_be[i]=0;
2275                    r_write_to_init_cmd_data[i] = 0;
2276                }
[200]2277                r_write_fsm = WRITE_BC_XRAM_REQ;
[184]2278
2279#if DEBUG_MEMC_WRITE
2280if( m_debug_write_fsm )
2281{
[200]2282    std::cout << "  <MEMC.WRITE_BC_CC_SEND> Post a broadcast request to INIT_CMD FSM" << std::endl;
[184]2283}
2284#endif
[2]2285            }
[184]2286            break;
[2]2287        }
[200]2288        ///////////////////////
2289        case WRITE_BC_XRAM_REQ:   // Post a put request to IXR_CMD FSM
[2]2290        {
[184]2291            if ( !r_write_to_ixr_cmd_req )
2292            {
2293                r_write_to_ixr_cmd_req     = true;
2294                r_write_to_ixr_cmd_write   = true;
2295                r_write_to_ixr_cmd_nline   = m_nline[(vci_addr_t)(r_write_address.read())];
2296                r_write_to_ixr_cmd_trdid   = r_write_trt_index.read();
2297
2298                for(size_t i=0; i<m_words; i++) r_write_to_ixr_cmd_data[i] = r_write_data[i];
2299
2300                r_write_fsm = WRITE_IDLE;
2301
2302#if DEBUG_MEMC_WRITE
2303if( m_debug_write_fsm )
2304{
[200]2305    std::cout << "  <MEMC.WRITE_BC_XRAM_REQ> Post a put request to IXR_CMD FSM" << std::endl;
[184]2306}
2307#endif
[2]2308            }
[184]2309            break;
[2]2310        }
2311    } // end switch r_write_fsm
2312
2313    ///////////////////////////////////////////////////////////////////////
2314    //          IXR_CMD FSM
2315    ///////////////////////////////////////////////////////////////////////
2316    // The IXR_CMD fsm controls the command packets to the XRAM :
[200]2317    // - It sends a single cell VCI read request to the XRAM in case of MISS
[184]2318    // posted by the READ, WRITE or SC FSMs : the TRDID field contains
[2]2319    // the Transaction Tab index.
2320    // The VCI response is a multi-cell packet : the N cells contain
2321    // the N data words.
[184]2322    // - It sends a multi-cell VCI write when the XRAM_RSP FSM, WRITE FSM
2323    // or SC FSM request to save a dirty line to the XRAM.
[2]2324    // The VCI response is a single cell packet.
[184]2325    // This FSM handles requests from the READ, WRITE, SC & XRAM_RSP FSMs
[2]2326    // with a round-robin priority.
2327    ////////////////////////////////////////////////////////////////////////
2328
[184]2329    switch ( r_ixr_cmd_fsm.read() )
2330    {
2331        ////////////////////////
2332        case IXR_CMD_READ_IDLE:
[2]2333        if      ( r_write_to_ixr_cmd_req )     r_ixr_cmd_fsm = IXR_CMD_WRITE_NLINE;
[184]2334        else if ( r_sc_to_ixr_cmd_req  )       r_ixr_cmd_fsm = IXR_CMD_SC_NLINE;
[2]2335        else if ( r_xram_rsp_to_ixr_cmd_req  ) r_ixr_cmd_fsm = IXR_CMD_XRAM_DATA;
2336        else if ( r_read_to_ixr_cmd_req  )     r_ixr_cmd_fsm = IXR_CMD_READ_NLINE;
2337        break;
2338        ////////////////////////
[184]2339        case IXR_CMD_WRITE_IDLE:
2340        if      ( r_sc_to_ixr_cmd_req  )       r_ixr_cmd_fsm = IXR_CMD_SC_NLINE;
[2]2341        else if ( r_xram_rsp_to_ixr_cmd_req  ) r_ixr_cmd_fsm = IXR_CMD_XRAM_DATA;
2342        else if ( r_read_to_ixr_cmd_req  )     r_ixr_cmd_fsm = IXR_CMD_READ_NLINE;
2343        else if ( r_write_to_ixr_cmd_req )     r_ixr_cmd_fsm = IXR_CMD_WRITE_NLINE;
2344        break;
2345        ////////////////////////
[184]2346        case IXR_CMD_SC_IDLE:
[2]2347        if      ( r_xram_rsp_to_ixr_cmd_req  ) r_ixr_cmd_fsm = IXR_CMD_XRAM_DATA;
2348        else if ( r_read_to_ixr_cmd_req  )     r_ixr_cmd_fsm = IXR_CMD_READ_NLINE;
2349        else if ( r_write_to_ixr_cmd_req )     r_ixr_cmd_fsm = IXR_CMD_WRITE_NLINE;
[184]2350        else if ( r_sc_to_ixr_cmd_req  )       r_ixr_cmd_fsm = IXR_CMD_SC_NLINE;
[2]2351        break;
2352        ////////////////////////
[184]2353        case IXR_CMD_XRAM_IDLE:
[2]2354        if      ( r_read_to_ixr_cmd_req  )     r_ixr_cmd_fsm = IXR_CMD_READ_NLINE;
2355        else if ( r_write_to_ixr_cmd_req )     r_ixr_cmd_fsm = IXR_CMD_WRITE_NLINE;
[184]2356        else if ( r_sc_to_ixr_cmd_req  )       r_ixr_cmd_fsm = IXR_CMD_SC_NLINE;
[2]2357        else if ( r_xram_rsp_to_ixr_cmd_req  ) r_ixr_cmd_fsm = IXR_CMD_XRAM_DATA;
2358        break;
[200]2359        /////////////////////////       // send a get request to XRAM
[184]2360        case IXR_CMD_READ_NLINE:
2361        if ( p_vci_ixr.cmdack )
2362        {
2363            r_ixr_cmd_fsm = IXR_CMD_READ_IDLE;         
2364            r_read_to_ixr_cmd_req = false;
2365
2366#if DEBUG_MEMC_IXR_CMD
2367if( m_debug_ixr_cmd_fsm )
2368{
[200]2369    std::cout << "  <MEMC.IXR_CMD_READ_NLINE> Send a get request to xram" << std::endl;
[184]2370}
2371#endif
[2]2372        }
2373        break;
2374        //////////////////////////
[200]2375        case IXR_CMD_WRITE_NLINE:           // send a put or get command to XRAM
[184]2376        if ( p_vci_ixr.cmdack )
2377        {
2378            if( r_write_to_ixr_cmd_write.read())
2379            {
2380                if ( r_ixr_cmd_cpt.read() == (m_words - 1) )
2381                {
2382                    r_ixr_cmd_cpt = 0;
2383                    r_ixr_cmd_fsm = IXR_CMD_WRITE_IDLE;
2384                    r_write_to_ixr_cmd_req = false;
2385                }
2386                else
2387                {
2388                    r_ixr_cmd_cpt = r_ixr_cmd_cpt + 1;
2389                }
2390
2391#if DEBUG_MEMC_IXR_CMD
2392if( m_debug_ixr_cmd_fsm )
2393{
[200]2394    std::cout << "  <MEMC.IXR_CMD_WRITE_NLINE> Send a put request to xram" << std::endl;
[184]2395}
2396#endif
2397            }
2398            else
2399            {
2400                r_ixr_cmd_fsm = IXR_CMD_WRITE_IDLE;             
2401                r_write_to_ixr_cmd_req = false;
2402
2403#if DEBUG_MEMC_IXR_CMD
2404if( m_debug_ixr_cmd_fsm )
2405{
[200]2406    std::cout << "  <MEMC.IXR_CMD_WRITE_NLINE> Send a get request to xram" << std::endl;
[184]2407}
2408#endif
[2]2409            }
2410        }
2411        break;
[184]2412        //////////////////////
[200]2413        case IXR_CMD_SC_NLINE:      // send a put or get command to XRAM
[184]2414        if ( p_vci_ixr.cmdack )
2415        {
2416            if( r_sc_to_ixr_cmd_write.read())
2417            {
2418                if ( r_ixr_cmd_cpt.read() == (m_words - 1) )
2419                {
2420                    r_ixr_cmd_cpt = 0;
2421                    r_ixr_cmd_fsm = IXR_CMD_SC_IDLE;
2422                    r_sc_to_ixr_cmd_req = false;
2423                }
2424                else
2425                {
2426                    r_ixr_cmd_cpt = r_ixr_cmd_cpt + 1;
2427                }
2428
2429#if DEBUG_MEMC_IXR_CMD
2430if( m_debug_ixr_cmd_fsm )
2431{
[200]2432    std::cout << "  <MEMC.IXR_CMD_SC_NLINE> Send a put request to xram" << std::endl;
[184]2433}
2434#endif
2435            }
2436            else
2437            {
2438                r_ixr_cmd_fsm = IXR_CMD_SC_IDLE;               
2439                r_sc_to_ixr_cmd_req = false;
2440
2441#if DEBUG_MEMC_IXR_CMD
2442if( m_debug_ixr_cmd_fsm )
2443{
[200]2444    std::cout << "  <MEMC.IXR_CMD_SC_NLINE> Send a get request to xram" << std::endl;
[184]2445}
2446#endif
[2]2447            }
2448        }
2449        break;
2450        ////////////////////////
[200]2451        case IXR_CMD_XRAM_DATA:     // send a put command to XRAM
[184]2452        if ( p_vci_ixr.cmdack )
2453        {
2454            if ( r_ixr_cmd_cpt.read() == (m_words - 1) )
2455            {
2456                r_ixr_cmd_cpt = 0;
2457                r_ixr_cmd_fsm = IXR_CMD_XRAM_IDLE;
2458                r_xram_rsp_to_ixr_cmd_req = false;
2459            }
2460            else
2461            {
2462                r_ixr_cmd_cpt = r_ixr_cmd_cpt + 1;
2463            }
2464
2465#if DEBUG_MEMC_IXR_CMD
2466if( m_debug_ixr_cmd_fsm )
2467{
[200]2468    std::cout << "  <MEMC.IXR_CMD_XRAM_DATA> Send a put request to xram" << std::endl;
[184]2469}
2470#endif
[2]2471        }
2472        break;
2473
2474    } // end switch r_ixr_cmd_fsm
2475
2476    ////////////////////////////////////////////////////////////////////////////
2477    //                IXR_RSP FSM
2478    ////////////////////////////////////////////////////////////////////////////
2479    // The IXR_RSP FSM receives the response packets from the XRAM,
[184]2480    // for both put transaction, and get transaction.
[2]2481    //
[184]2482    // - A response to a put request is a single-cell VCI packet.
[2]2483    // The Transaction Tab index is contained in the RTRDID field.
2484    // The FSM takes the lock protecting the TRT, and the corresponding
2485    // entry is erased.
2486    // 
[184]2487    // - A response to a get request is a multi-cell VCI packet.
[2]2488    // The Transaction Tab index is contained in the RTRDID field.
2489    // The N cells contain the N words of the cache line in the RDATA field.
2490    // The FSM takes the lock protecting the TRT to store the line in the TRT
2491    // (taking into account the write requests already stored in the TRT).
2492    // When the line is completely written, the corresponding rok signal is set.
2493    ///////////////////////////////////////////////////////////////////////////////
2494
[184]2495    switch ( r_ixr_rsp_fsm.read() )
2496    {
[200]2497        //////////////////
[184]2498        case IXR_RSP_IDLE:      // test if it's a get or a put transaction
2499        {
2500            if ( p_vci_ixr.rspval.read() )
2501            {
2502                r_ixr_rsp_cpt   = 0;
2503                r_ixr_rsp_trt_index = p_vci_ixr.rtrdid.read();
2504                if ( p_vci_ixr.reop.read() && !(p_vci_ixr.rerror.read()&0x1))  // put transaction
2505                {
2506                    r_ixr_rsp_fsm = IXR_RSP_ACK;
[2]2507
[184]2508#if DEBUG_MEMC_IXR_RSP
2509if( m_debug_ixr_rsp_fsm )
2510{
2511    std::cout << "  <MEMC.IXR_RSP_IDLE> Response from XRAM to a put transaction" << std::endl;
2512}
2513#endif
2514                }
2515                else                                                           // get transaction
2516                {
2517                    r_ixr_rsp_fsm = IXR_RSP_TRT_READ;
2518
2519#if DEBUG_MEMC_IXR_RSP
2520if( m_debug_ixr_rsp_fsm )
2521{
2522    std::cout << "  <MEMC.IXR_RSP_IDLE> Response from XRAM to a get transaction" << std::endl;
2523}
2524#endif
2525                }
2526            }
2527            break; 
[2]2528        }
2529        ////////////////////////
[184]2530        case IXR_RSP_ACK:        // Aknowledge the VCI response
[138]2531        {
[184]2532            if(p_vci_ixr.rspval.read()) r_ixr_rsp_fsm = IXR_RSP_TRT_ERASE;
2533
2534#if DEBUG_MEMC_IXR_RSP
2535if( m_debug_ixr_rsp_fsm )
2536{
2537    std::cout << "  <MEMC.IXR_RSP_ACK>" << std::endl;
2538}
2539#endif
[138]2540            break;
2541        }
[2]2542        ////////////////////////
[184]2543        case IXR_RSP_TRT_ERASE:         // erase the entry in the TRT
[2]2544        {
[184]2545            if ( r_alloc_trt_fsm.read() == ALLOC_TRT_IXR_RSP )
2546            {
2547                m_transaction_tab.erase(r_ixr_rsp_trt_index.read());
2548                r_ixr_rsp_fsm = IXR_RSP_IDLE;
2549
2550#if DEBUG_MEMC_IXR_RSP
2551if( m_debug_ixr_rsp_fsm )
2552{
2553    std::cout << "  <MEMC.IXR_RSP_TRT_ERASE> Erase TRT entry "
2554              << r_ixr_rsp_trt_index.read() << std::endl;
[57]2555}
[2]2556#endif
[184]2557            }
2558            break;
[2]2559        }
2560        ///////////////////////
[184]2561        case IXR_RSP_TRT_READ:          // write data in the TRT
[2]2562        {
[184]2563            if ( (r_alloc_trt_fsm.read() == ALLOC_TRT_IXR_RSP) &&  p_vci_ixr.rspval )
2564            {
2565                size_t index    = r_ixr_rsp_trt_index.read();
2566                bool   eop      = p_vci_ixr.reop.read();
2567                data_t data     = p_vci_ixr.rdata.read();
2568                bool   error    = (p_vci_ixr.rerror.read()&0x1 == 0);
2569                assert(((eop == (r_ixr_rsp_cpt.read() == (m_words-1))) || p_vci_ixr.rerror.read())
2570                    and "Error in VCI_MEM_CACHE : invalid length for a response from XRAM");
2571                m_transaction_tab.write_rsp(index,
2572                                            r_ixr_rsp_cpt.read(),
2573                                            data,
2574                                            error);
2575                r_ixr_rsp_cpt = r_ixr_rsp_cpt.read() + 1;
2576                if ( eop )
2577                {
2578                    r_ixr_rsp_to_xram_rsp_rok[r_ixr_rsp_trt_index.read()]=true;
2579                    r_ixr_rsp_fsm = IXR_RSP_IDLE;
2580                }
2581
2582#if DEBUG_MEMC_IXR_RSP
2583if( m_debug_ixr_rsp_fsm )
2584{
2585    std::cout << "  <MEMC.IXR_RSP_TRT_READ> Writing a word in TRT : "
2586              << " index = " << std::dec << index
2587              << " / word = " << r_ixr_rsp_cpt.read()
2588              << " / data = " << std::hex << data << std::endl;
[57]2589}
[2]2590#endif
2591            }
[184]2592            break;
[2]2593        }
2594    } // end swich r_ixr_rsp_fsm
2595
2596    ////////////////////////////////////////////////////////////////////////////
2597    //                XRAM_RSP FSM
2598    ////////////////////////////////////////////////////////////////////////////
2599    // The XRAM_RSP FSM handles the incoming cache lines from the XRAM.
[184]2600    // The cache line has been written in the TRT by the IXR_CMD_FSM.
2601    // As the IXR_RSP FSM and the XRAM_RSP FSM are running in parallel,
2602    // there is as many flip-flops r_ixr_rsp_to_xram_rsp_rok[i]
2603    // as the number of entries in the TRT, that are handled with
2604    // a round-robin priority...
[2]2605    //
2606    // When a response is available, the corresponding TRT entry
[184]2607    // must be copied in a local buffer to be written in the cache.
2608    // The FSM takes the lock protecting the TRT, and the lock protecting the DIR.
[2]2609    // It selects a cache slot and writes the line in the cache.
2610    // If it was a read MISS, the XRAM_RSP FSM send a request to the TGT_RSP
2611    // FSM to return the cache line to the registered processor.
2612    // If there is no empty slot, a victim line is evicted, and
2613    // invalidate requests are sent to the L1 caches containing copies.
2614    // If this line is dirty, the XRAM_RSP FSM send a request to the IXR_CMD
2615    // FSM to save the victim line to the XRAM, and register the write transaction
2616    // in the TRT (using the entry previously used by the read transaction).
2617    ///////////////////////////////////////////////////////////////////////////////
2618
[184]2619    switch ( r_xram_rsp_fsm.read() )
2620    {
2621        ///////////////////
2622        case XRAM_RSP_IDLE:     // scan the XRAM responses to get the TRT index (round robin)
2623        {
2624            size_t ptr   = r_xram_rsp_trt_index.read();
2625            size_t lines = m_transaction_tab_lines;
2626            for( size_t i=0 ; i<lines ; i++)
2627            {
2628                size_t index=(i+ptr+1)%lines;
2629                if ( r_ixr_rsp_to_xram_rsp_rok[index] )
2630                {
2631                    r_xram_rsp_trt_index                = index;
2632                    r_ixr_rsp_to_xram_rsp_rok[index]    = false;
2633                    r_xram_rsp_fsm                      = XRAM_RSP_DIR_LOCK;
[2]2634
[184]2635#if DEBUG_MEMC_XRAM_RSP
2636if( m_debug_xram_rsp_fsm )
2637{       
2638    std::cout << "  <MEMC.XRAM_RSP_IDLE> Available cache line in TRT:"
2639              << " index = " << std::dec << index << std::endl;
[57]2640}
[2]2641#endif
[184]2642                    break;
2643                }
[2]2644            }
[184]2645            break; 
[2]2646        }
2647        ///////////////////////
[184]2648        case XRAM_RSP_DIR_LOCK:         // Takes the lock on the directory
[2]2649        {
[184]2650            if( r_alloc_dir_fsm.read() == ALLOC_DIR_XRAM_RSP )
2651            {
2652                r_xram_rsp_fsm = XRAM_RSP_TRT_COPY;
2653
2654#if DEBUG_MEMC_XRAM_RSP
2655if( m_debug_xram_rsp_fsm )
2656{       
2657    std::cout << "  <MEMC.XRAM_RSP_DIR_LOCK> Get access to directory" << std::endl;
[57]2658}
[2]2659#endif
[184]2660            }
2661            break;
[2]2662        }
2663        ///////////////////////
[184]2664        case XRAM_RSP_TRT_COPY:         // Takes the lock on TRT
2665                                    // Copy the TRT entry in a local buffer
2666                                    // and select a victim cache line
[2]2667        {
[184]2668            if ( (r_alloc_trt_fsm.read() == ALLOC_TRT_XRAM_RSP) )
2669            {
2670                // copy the TRT entry in the r_xram_rsp_trt_buf local buffer
2671                size_t  index = r_xram_rsp_trt_index.read();
2672                TransactionTabEntry    trt_entry(m_transaction_tab.read(index)); 
2673                r_xram_rsp_trt_buf.copy(trt_entry);  // TRT entry local buffer
[2]2674
[184]2675                // selects & extracts a victim line from cache
2676                size_t way = 0;
2677                size_t set = m_y[(vci_addr_t)(trt_entry.nline * m_words * 4)];
2678                DirectoryEntry victim(m_cache_directory.select(set, way));
[2]2679
[184]2680                bool inval = (victim.count && victim.valid) ;
[2]2681
[184]2682                // copy the victim line in a local buffer
2683                for (size_t i=0 ; i<m_words ; i++)
2684                    r_xram_rsp_victim_data[i] = m_cache_data[way][set][i];
2685                r_xram_rsp_victim_copy      = victim.owner.srcid;
[140]2686#if L1_MULTI_CACHE
[184]2687                r_xram_rsp_victim_copy_cache= victim.owner.cache_id;
[140]2688#endif
[184]2689                r_xram_rsp_victim_copy_inst = victim.owner.inst;
2690                r_xram_rsp_victim_count     = victim.count;
2691                r_xram_rsp_victim_ptr       = victim.ptr;
2692                r_xram_rsp_victim_way       = way;
2693                r_xram_rsp_victim_set       = set;
2694                r_xram_rsp_victim_nline     = victim.tag*m_sets + set;
2695                r_xram_rsp_victim_is_cnt    = victim.is_cnt;
2696                r_xram_rsp_victim_inval     = inval ;
2697                r_xram_rsp_victim_dirty     = victim.dirty;
[2]2698
[184]2699                if(!trt_entry.rerror)   r_xram_rsp_fsm = XRAM_RSP_INVAL_LOCK;
2700                else                            r_xram_rsp_fsm = XRAM_RSP_ERROR_ERASE;     
2701
2702#if DEBUG_MEMC_XRAM_RSP
2703if( m_debug_xram_rsp_fsm )
2704{
2705    std::cout << "  <MEMC.XRAM_RSP_TRT_COPY> Select a slot: "
2706              << " way = " << std::dec << way
2707              << " / set = " << set
2708              << " / inval_required = " << inval << std::endl;
[57]2709}
[2]2710#endif
[184]2711            }
2712            break;
[2]2713        }
[184]2714        /////////////////////////
2715        case XRAM_RSP_INVAL_LOCK:       // check a possible pending inval
[2]2716        {
[184]2717            if ( r_alloc_upt_fsm == ALLOC_UPT_XRAM_RSP )
2718            {
2719                size_t index;
2720                if (m_update_tab.search_inval(r_xram_rsp_trt_buf.nline, index))
2721                {
2722                    r_xram_rsp_fsm = XRAM_RSP_INVAL_WAIT;
2723
2724#if DEBUG_MEMC_XRAM_RSP
2725if( m_debug_xram_rsp_fsm )
2726{
2727    std::cout << "  <MEMC.XRAM_RSP_INVAL_LOCK> Get acces to UPT,"
2728              << " but an invalidation is already registered at this address" << std::endl;
2729    m_update_tab.print();
[57]2730}
[2]2731#endif
[184]2732
2733                }
2734                else if (m_update_tab.is_full() && r_xram_rsp_victim_inval.read())
2735                {
2736                    r_xram_rsp_fsm = XRAM_RSP_INVAL_WAIT;
2737
2738#if DEBUG_MEMC_XRAM_RSP
2739if( m_debug_xram_rsp_fsm )
2740{
2741    std::cout << "  <MEMC.XRAM_RSP_INVAL_LOCK> Get acces to UPT,"
2742              << " but the table is full" << std::endl;
2743    m_update_tab.print();
[57]2744}
[2]2745#endif
[184]2746                }
2747                else
2748                {
2749                    r_xram_rsp_fsm = XRAM_RSP_DIR_UPDT;
[2]2750
[184]2751#if DEBUG_MEMC_XRAM_RSP
2752if( m_debug_xram_rsp_fsm )
2753{
2754    std::cout << "  <MEMC.XRAM_RSP_INVAL_LOCK> Get acces to UPT" << std::endl;
[57]2755}
[2]2756#endif
[184]2757                }
[2]2758            }
[184]2759            break;
[2]2760        }
[184]2761        /////////////////////////
2762        case XRAM_RSP_INVAL_WAIT:       // returns to DIR_LOCK to retry
[2]2763        {
[184]2764            r_xram_rsp_fsm = XRAM_RSP_DIR_LOCK;
2765            break;
[2]2766        }
2767        ///////////////////////
[184]2768        case XRAM_RSP_DIR_UPDT:         // updates the cache (both data & directory)
2769                                        // and possibly set an inval request in UPT
[2]2770        {
[184]2771            // signals generation
2772            bool inst_read = (r_xram_rsp_trt_buf.trdid & 0x2) && r_xram_rsp_trt_buf.proc_read;
2773            bool cached_read = (r_xram_rsp_trt_buf.trdid & 0x1) && r_xram_rsp_trt_buf.proc_read;
2774            // update data
2775            size_t set   = r_xram_rsp_victim_set.read();
2776            size_t way   = r_xram_rsp_victim_way.read();
2777            for(size_t i=0; i<m_words ; i++) m_cache_data[way][set][i] = r_xram_rsp_trt_buf.wdata[i];
2778            // compute dirty
2779            bool dirty = false;
2780            for(size_t i=0; i<m_words;i++) dirty = dirty || (r_xram_rsp_trt_buf.wdata_be[i] != 0);
2781            // update directory
2782            DirectoryEntry entry;
2783            entry.valid   = true;
2784            entry.is_cnt  = false;
2785            entry.lock    = false;
2786            entry.dirty   = dirty;
2787            entry.tag     = r_xram_rsp_trt_buf.nline / m_sets;
2788            entry.ptr     = 0;
2789            if(cached_read)
2790            {
2791                entry.owner.srcid   = r_xram_rsp_trt_buf.srcid;
[140]2792#if L1_MULTI_CACHE
[184]2793                entry.owner.cache_id= r_xram_rsp_trt_buf.pktid;
[140]2794#endif
[184]2795                entry.owner.inst    = inst_read;
2796                entry.count         = 1;
2797            }
2798            else
2799            {
2800                entry.owner.srcid    = 0;
[140]2801#if L1_MULTI_CACHE
[184]2802                entry.owner.cache_id = 0;
[140]2803#endif
[184]2804                entry.owner.inst     = 0;
2805                entry.count          = 0;
2806            }
2807            m_cache_directory.write(set, way, entry);
[2]2808
[184]2809            if (r_xram_rsp_victim_inval.read())
2810            {
2811                bool   brdcast          = r_xram_rsp_victim_is_cnt.read();
2812                size_t index            = 0;
2813                size_t count_copies     = r_xram_rsp_victim_count.read();
[2]2814
[184]2815                bool   wok = m_update_tab.set(  false,          // it's an inval transaction
2816                                                brdcast,        // set brdcast bit
2817                                                false,          // it does not need a response
2818                                                0,              // srcid
2819                                                0,              // trdid
2820                                                0,              // pktid
2821                                                r_xram_rsp_victim_nline.read(),
2822                                                count_copies,
2823                                                index);
2824                r_xram_rsp_upt_index = index;
[2]2825
[184]2826                if (!wok)
2827                {
2828                    std::cout << "VCI_MEM_CACHE ERROR " << name() << " XRAM_RSP_HEAP_LAST state" << std::endl;
2829                    std::cout << "an update_tab entry was free but write is unsuccessful" << std::endl;
2830                    exit(0);
2831                }
2832            }
2833
2834#if DEBUG_MEMC_XRAM_RSP
2835if( m_debug_xram_rsp_fsm )
2836{
2837    std::cout << "  <MEMC.XRAM_RSP_DIR_UPDT> Directory update: "
2838              << " way = " << std::dec << way
2839              << " / set = " << set
2840              << " / count = " << entry.count
2841              << " / is_cnt = " << entry.is_cnt << std::endl;
2842    if (r_xram_rsp_victim_inval.read())
2843    std::cout << "                           Invalidation request for victim line "
2844              << std::hex << r_xram_rsp_victim_nline.read()
2845              << " / broadcast = " << r_xram_rsp_victim_is_cnt.read() << std::endl;
[57]2846}
[2]2847#endif
2848
[184]2849            // If the victim is not dirty, we don't need another XRAM  put transaction,
2850            // and we canwe erase the TRT entry
2851            if (!r_xram_rsp_victim_dirty.read())  m_transaction_tab.erase(r_xram_rsp_trt_index.read());
2852
2853            // Next state
2854            if      ( r_xram_rsp_victim_dirty.read())       r_xram_rsp_fsm = XRAM_RSP_TRT_DIRTY;
2855            else if ( r_xram_rsp_trt_buf.proc_read  )       r_xram_rsp_fsm = XRAM_RSP_DIR_RSP;
2856            else if ( r_xram_rsp_victim_inval.read())       r_xram_rsp_fsm = XRAM_RSP_INVAL;
2857            else                                            r_xram_rsp_fsm = XRAM_RSP_IDLE;
2858            break;
[2]2859        }
2860        ////////////////////////
[184]2861        case XRAM_RSP_TRT_DIRTY:  // set the TRT entry (write to XRAM) if the victim is dirty
[2]2862        {
[184]2863            if ( r_alloc_trt_fsm.read() == ALLOC_TRT_XRAM_RSP )
2864            {
2865                m_transaction_tab.set( r_xram_rsp_trt_index.read(),
2866                                       false,                           // write to XRAM
2867                                       r_xram_rsp_victim_nline.read(),  // line index
2868                                       0,
2869                                       0,
2870                                       0,
2871                                       false,
2872                                       0,
2873                                       0,
2874                                       std::vector<be_t>(m_words,0),
2875                                       std::vector<data_t>(m_words,0) );
2876
2877#if DEBUG_MEMC_XRAM_RSP
2878if( m_debug_xram_rsp_fsm )
2879{
2880    std::cout << "  <MEMC.XRAM_RSP_TRT_DIRTY> Set TRT entry for the put transaction:"
2881              << " dirty victim line = " << r_xram_rsp_victim_nline.read() << std::endl;
[57]2882}
[2]2883#endif
[184]2884                if      ( r_xram_rsp_trt_buf.proc_read  )       r_xram_rsp_fsm = XRAM_RSP_DIR_RSP;
2885                else if ( r_xram_rsp_victim_inval.read())       r_xram_rsp_fsm = XRAM_RSP_INVAL;
2886                else                                            r_xram_rsp_fsm = XRAM_RSP_WRITE_DIRTY;
2887            }
2888            break;
[2]2889        }
2890        //////////////////////
[184]2891        case XRAM_RSP_DIR_RSP:     // Request a response to TGT_RSP FSM
[2]2892        {
[184]2893            if ( !r_xram_rsp_to_tgt_rsp_req.read() )
2894            {
2895                r_xram_rsp_to_tgt_rsp_srcid = r_xram_rsp_trt_buf.srcid;
2896                r_xram_rsp_to_tgt_rsp_trdid = r_xram_rsp_trt_buf.trdid;
2897                r_xram_rsp_to_tgt_rsp_pktid = r_xram_rsp_trt_buf.pktid;
2898                for (size_t i=0; i < m_words; i++) r_xram_rsp_to_tgt_rsp_data[i] = r_xram_rsp_trt_buf.wdata[i];
2899                r_xram_rsp_to_tgt_rsp_word   = r_xram_rsp_trt_buf.word_index;
2900                r_xram_rsp_to_tgt_rsp_length = r_xram_rsp_trt_buf.read_length;
2901                r_xram_rsp_to_tgt_rsp_rerror = false;
2902                r_xram_rsp_to_tgt_rsp_req    = true;
[2]2903
[184]2904                if      ( r_xram_rsp_victim_inval ) r_xram_rsp_fsm = XRAM_RSP_INVAL;
2905                else if ( r_xram_rsp_victim_dirty ) r_xram_rsp_fsm = XRAM_RSP_WRITE_DIRTY;
2906                else                                r_xram_rsp_fsm = XRAM_RSP_IDLE;
[2]2907
[184]2908
2909#if DEBUG_MEMC_XRAM_RSP
2910if( m_debug_xram_rsp_fsm )
2911{
2912    std::cout << "  <MEMC.XRAM_RSP_DIR_RSP> Request the TGT_RSP FSM to return data:"
2913              << " rsrcid = " << std::hex << r_xram_rsp_trt_buf.srcid
2914              << " / address = " << r_xram_rsp_trt_buf.nline*m_words*4
2915              << " / nwords = " << std::dec << r_xram_rsp_trt_buf.read_length << std::endl;
[57]2916}
[2]2917#endif
[184]2918            }
2919            break;
[2]2920        }
2921        ////////////////////
[184]2922        case XRAM_RSP_INVAL:    // send invalidate request to INIT_CMD FSM
[2]2923        {
[184]2924            if(   !r_xram_rsp_to_init_cmd_multi_req.read() &&
2925                  !r_xram_rsp_to_init_cmd_brdcast_req.read() )
2926            {         
2927                bool multi_req = !r_xram_rsp_victim_is_cnt.read();
2928                bool last_multi_req  = multi_req && (r_xram_rsp_victim_count.read() == 1);
2929                bool not_last_multi_req = multi_req && (r_xram_rsp_victim_count.read() != 1);
[2]2930
[184]2931                r_xram_rsp_to_init_cmd_multi_req    = last_multi_req;
2932                r_xram_rsp_to_init_cmd_brdcast_req  = r_xram_rsp_victim_is_cnt.read();
2933                r_xram_rsp_to_init_cmd_nline        = r_xram_rsp_victim_nline.read();
2934                r_xram_rsp_to_init_cmd_trdid        = r_xram_rsp_upt_index;
2935                xram_rsp_to_init_cmd_fifo_srcid     = r_xram_rsp_victim_copy.read();
2936                xram_rsp_to_init_cmd_fifo_inst      = r_xram_rsp_victim_copy_inst.read();
[140]2937#if L1_MULTI_CACHE
[184]2938                xram_rsp_to_init_cmd_fifo_cache_id  = r_xram_rsp_victim_copy_cache.read();
[140]2939#endif
[184]2940                xram_rsp_to_init_cmd_fifo_put       = multi_req;
2941                r_xram_rsp_next_ptr                 = r_xram_rsp_victim_ptr.read();
[2]2942
[184]2943                if ( r_xram_rsp_victim_dirty )  r_xram_rsp_fsm = XRAM_RSP_WRITE_DIRTY;
2944                else if (not_last_multi_req)    r_xram_rsp_fsm = XRAM_RSP_HEAP_ERASE;
2945                else                            r_xram_rsp_fsm = XRAM_RSP_IDLE;
2946
2947#if DEBUG_MEMC_XRAM_RSP
2948if( m_debug_xram_rsp_fsm )
2949{
2950    std::cout << "  <MEMC.XRAM_RSP_INVAL> Send an inval request to INIT_CMD FSM:"
2951              << " victim line = " << r_xram_rsp_victim_nline.read() << std::endl;
[57]2952}
[2]2953#endif
2954          }
2955          break;
2956        }
2957        //////////////////////////
[184]2958        case XRAM_RSP_WRITE_DIRTY:      // send a write request to IXR_CMD FSM
[2]2959        {
[184]2960            if ( !r_xram_rsp_to_ixr_cmd_req.read() )
2961            {
2962                r_xram_rsp_to_ixr_cmd_req = true;
2963                r_xram_rsp_to_ixr_cmd_nline = r_xram_rsp_victim_nline.read();
2964                r_xram_rsp_to_ixr_cmd_trdid = r_xram_rsp_trt_index.read();
2965                for(size_t i=0; i<m_words ; i++) r_xram_rsp_to_ixr_cmd_data[i] = r_xram_rsp_victim_data[i];
2966                m_cpt_write_dirty++;
2967
2968                bool multi_req = !r_xram_rsp_victim_is_cnt.read() && r_xram_rsp_victim_inval.read();
2969                bool not_last_multi_req = multi_req && (r_xram_rsp_victim_count.read() != 1);
2970                if ( not_last_multi_req )   r_xram_rsp_fsm = XRAM_RSP_HEAP_ERASE;
2971                else                        r_xram_rsp_fsm = XRAM_RSP_IDLE;
2972
2973#if DEBUG_MEMC_XRAM_RSP
2974if( m_debug_xram_rsp_fsm )
2975{
2976    std::cout << "  <MEMC.XRAM_RSP_WRITE_DIRTY> Send the put request to IXR_CMD FSM:"
2977              << " victim line = " << r_xram_rsp_victim_nline.read() << std::endl;
[57]2978}
[2]2979#endif
[184]2980            }
2981            break;
[2]2982        }
[184]2983        /////////////////////////
2984        case XRAM_RSP_HEAP_ERASE:       // erase the list of copies and sent invalidations
[2]2985        {
[184]2986            if( r_alloc_heap_fsm.read() == ALLOC_HEAP_XRAM_RSP )
2987            {
2988                HeapEntry entry = m_heap.read(r_xram_rsp_next_ptr.read());
2989
2990                xram_rsp_to_init_cmd_fifo_srcid    = entry.owner.srcid;
[140]2991#if L1_MULTI_CACHE
[184]2992                xram_rsp_to_init_cmd_fifo_cache_id = entry.owner.cache_id;
[140]2993#endif
[184]2994                xram_rsp_to_init_cmd_fifo_inst  = entry.owner.inst;
2995                xram_rsp_to_init_cmd_fifo_put   = true;
2996                if( m_xram_rsp_to_init_cmd_inst_fifo.wok() )
2997                {
2998                    r_xram_rsp_next_ptr = entry.next;
2999                    if( entry.next == r_xram_rsp_next_ptr.read() ) // last copy
3000                    {
3001                        r_xram_rsp_to_init_cmd_multi_req = true;
3002                        r_xram_rsp_fsm = XRAM_RSP_HEAP_LAST;
3003                    }
3004                    else
3005                    {
3006                        r_xram_rsp_fsm = XRAM_RSP_HEAP_ERASE;
3007                    }
3008                }
3009                else
3010                {
3011                    r_xram_rsp_fsm = XRAM_RSP_HEAP_ERASE;
3012                }
3013
3014#if DEBUG_MEMC_XRAM_RSP
3015if( m_debug_xram_rsp_fsm )
3016{
3017    std::cout << "  <MEMC.XRAM_RSP_HEAP_ERASE> Erase the list of copies:"
3018              << " srcid = " << entry.owner.srcid
3019              << " / inst = " << entry.owner.inst << std::endl;
3020}
3021#endif
[2]3022            }
[184]3023            break;
[2]3024        }
[184]3025        /////////////////////////
3026        case XRAM_RSP_HEAP_LAST:        // last member of the list
[2]3027        {
[184]3028            if ( r_alloc_heap_fsm.read() != ALLOC_HEAP_XRAM_RSP )
3029            {
3030                std::cout << "VCI_MEM_CACHE ERROR " << name() << " XRAM_RSP_HEAP_LAST state" << std::endl;
3031                std::cout << "bad HEAP allocation" << std::endl;
3032                exit(0);
3033            }
3034            size_t free_pointer = m_heap.next_free_ptr();
[2]3035
[184]3036            HeapEntry last_entry;
3037            last_entry.owner.srcid    = 0;
[140]3038#if L1_MULTI_CACHE
[184]3039            last_entry.owner.cache_id = 0;
[140]3040#endif
[184]3041            last_entry.owner.inst     = false;
3042            if(m_heap.is_full())
3043            {
3044                last_entry.next     = r_xram_rsp_next_ptr.read();
3045                m_heap.unset_full();
3046            }
3047            else
3048            {
3049                last_entry.next     = free_pointer;
3050            }
[2]3051
[184]3052            m_heap.write_free_ptr(r_xram_rsp_victim_ptr.read());
3053            m_heap.write(r_xram_rsp_next_ptr.read(),last_entry);
[2]3054
[184]3055            r_xram_rsp_fsm = XRAM_RSP_IDLE;
[2]3056
[184]3057#if DEBUG_MEMC_XRAM_RSP
3058if( m_debug_xram_rsp_fsm )
3059{
3060    std::cout << "  <MEMC.XRAM_RSP_HEAP_LAST> Heap housekeeping" << std::endl;
3061}
3062#endif
3063            break;
[2]3064        }
[184]3065        // ///////////////////////
3066        case XRAM_RSP_ERROR_ERASE:      // erase TRT entry in case of error
[138]3067        {
[184]3068            m_transaction_tab.erase(r_xram_rsp_trt_index.read());
[138]3069
[184]3070            // Next state
3071            if ( r_xram_rsp_trt_buf.proc_read  ) r_xram_rsp_fsm = XRAM_RSP_ERROR_RSP;
3072            else                                 r_xram_rsp_fsm = XRAM_RSP_IDLE;
3073
3074#if DEBUG_MEMC_XRAM_RSP
3075if( m_debug_xram_rsp_fsm )
3076{
3077    std::cout << "  <MEMC.XRAM_RSP_ERROR_ERASE> Error reported by XRAM / erase the TRT entry" << std::endl;
[138]3078}
3079#endif
[184]3080            break;
[138]3081        }
[184]3082        ////////////////////////
3083        case XRAM_RSP_ERROR_RSP:     // Request an error response to TGT_RSP FSM
[138]3084        {
[184]3085            if ( !r_xram_rsp_to_tgt_rsp_req.read() )
3086            {
3087                r_xram_rsp_to_tgt_rsp_srcid  = r_xram_rsp_trt_buf.srcid;
3088                r_xram_rsp_to_tgt_rsp_trdid  = r_xram_rsp_trt_buf.trdid;
3089                r_xram_rsp_to_tgt_rsp_pktid  = r_xram_rsp_trt_buf.pktid;
3090                for (size_t i=0; i < m_words; i++) r_xram_rsp_to_tgt_rsp_data[i] = r_xram_rsp_trt_buf.wdata[i];
3091                r_xram_rsp_to_tgt_rsp_word   = r_xram_rsp_trt_buf.word_index;
3092                r_xram_rsp_to_tgt_rsp_length = r_xram_rsp_trt_buf.read_length;
3093                r_xram_rsp_to_tgt_rsp_rerror = true;
3094                r_xram_rsp_to_tgt_rsp_req    = true;
[138]3095
[184]3096                r_xram_rsp_fsm = XRAM_RSP_IDLE;
[138]3097
[184]3098#if DEBUG_MEMC_XRAM_RSP
3099if( m_debug_xram_rsp_fsm )
3100{
3101    std::cout << "  <MEMC.XRAM_RSP_ERROR_RSP> Request a response error to TGT_RSP FSM:"
3102              << " srcid = " << r_xram_rsp_trt_buf.srcid << std::endl;
[138]3103}
3104#endif
[184]3105            }
3106            break;
[138]3107        }
[2]3108    } // end swich r_xram_rsp_fsm
3109
3110    ////////////////////////////////////////////////////////////////////////////////////
3111    //          CLEANUP FSM
3112    ////////////////////////////////////////////////////////////////////////////////////
3113    // The CLEANUP FSM handles the cleanup request from L1 caches.
[184]3114    // It accesses the cache directory and the heap to update the list of copies.
[2]3115    ////////////////////////////////////////////////////////////////////////////////////
3116
[184]3117
3118    switch ( r_cleanup_fsm.read() )
3119    {
3120        //////////////////
3121        case CLEANUP_IDLE:
[2]3122        {
[184]3123            if ( p_vci_tgt_cleanup.cmdval.read() )
[116]3124            {
[184]3125                if (p_vci_tgt_cleanup.srcid.read() >= m_initiators )
3126                {
3127                    std::cout << "VCI_MEM_CACHE ERROR " << name()
3128                              << " CLEANUP_IDLE state" << std::endl;
3129                    std::cout << "illegal srcid for  cleanup request" << std::endl;
3130                    exit(0);
3131                }
[140]3132
[184]3133                bool reached = false;
3134                for ( size_t index = 0 ; index < ncseg && !reached ; index++ )
3135                {
3136                    if ( m_cseg[index]->contains((addr_t)(p_vci_tgt_cleanup.address.read())) )
3137                        reached = true;
3138                }
3139                // only write request to a mapped address that are not broadcast are handled
3140                if ( (p_vci_tgt_cleanup.cmd.read() == vci_param::CMD_WRITE) &&
3141                     ((p_vci_tgt_cleanup.address.read() & 0x3) == 0) && reached)
3142                {
3143                    addr_t line = (addr_t)(m_nline[(vci_addr_t)(p_vci_tgt_cleanup.address.read())]);
[2]3144
[184]3145                    r_cleanup_nline = line;
3146                    r_cleanup_srcid = p_vci_tgt_cleanup.srcid.read();
3147                    r_cleanup_trdid = p_vci_tgt_cleanup.trdid.read();
3148                    r_cleanup_pktid = p_vci_tgt_cleanup.pktid.read();
3149                    r_cleanup_fsm   = CLEANUP_DIR_LOCK;
[2]3150
[184]3151#if DEBUG_MEMC_CLEANUP
3152if( m_debug_cleanup_fsm )
3153{
3154    std::cout << "  <MEMC.CLEANUP_IDLE> Cleanup request:" << std::hex
3155              << " line = " << line * m_words * 4
3156              << " / owner_id = " << p_vci_tgt_cleanup.srcid.read()
3157              << " / owner_ins = " << (p_vci_tgt_cleanup.trdid.read()&0x1)
3158              << std::endl;
3159}
3160#endif
3161                    m_cpt_cleanup++;
3162                }
[2]3163            }
[184]3164            break;
[2]3165        }
3166        //////////////////////
[184]3167        case CLEANUP_DIR_LOCK:  // test directory status
[2]3168        {
[184]3169            if ( r_alloc_dir_fsm.read() == ALLOC_DIR_CLEANUP )
3170            {
3171                // Read the directory
3172                size_t way = 0;
3173                    addr_t cleanup_address = r_cleanup_nline.read() * m_words * 4;
3174                DirectoryEntry entry   = m_cache_directory.read(cleanup_address , way);
3175                r_cleanup_is_cnt       = entry.is_cnt;
3176                r_cleanup_dirty        = entry.dirty;
3177                r_cleanup_tag          = entry.tag;
3178                r_cleanup_lock         = entry.lock;
3179                r_cleanup_way          = way;
3180                r_cleanup_copy         = entry.owner.srcid;
3181#if L1_MULTI_CACHE
3182                r_cleanup_copy_cache= entry.owner.cache_id;
3183#endif
3184                r_cleanup_copy_inst    = entry.owner.inst;
3185                r_cleanup_count        = entry.count;
3186                r_cleanup_ptr          = entry.ptr;
[2]3187
[184]3188                if( entry.valid) //  hit : the copy must be cleared 
3189                {
3190                    if ( (entry.count==1) || (entry.is_cnt) )  // no access to the heap
3191                    {
3192                        r_cleanup_fsm = CLEANUP_DIR_WRITE;
3193                    }
3194                    else                                        // access to the heap
3195                    {
3196                        r_cleanup_fsm = CLEANUP_HEAP_LOCK;
3197                    }
3198                }
3199                else            // miss : we must check the update table
3200                {
3201                    r_cleanup_fsm = CLEANUP_UPT_LOCK;
3202                }
3203
3204#if DEBUG_MEMC_CLEANUP
3205if( m_debug_cleanup_fsm )
3206{
3207    std::cout << "  <MEMC.CLEANUP_DIR_LOCK> Test directory status: " << std::hex
3208              << " line = " << r_cleanup_nline.read() * m_words * 4
3209              << " / hit = " << entry.valid
3210              << " / dir_id = " << entry.owner.srcid
3211              << " / dir_ins = " << entry.owner.inst
3212              << " / search_id = " << r_cleanup_srcid.read()
3213              << " / search_ins = " << (r_cleanup_trdid.read()&0x1)
3214              << " / count = " << entry.count
3215              << " / is_cnt = " << entry.is_cnt << std::endl;
[57]3216}
[2]3217#endif
3218            }
[184]3219            break;
[2]3220        }
3221        ///////////////////////
[184]3222        case CLEANUP_DIR_WRITE:  //  update the directory entry without heap access
[2]3223        {
[184]3224            if ( r_alloc_dir_fsm.read() != ALLOC_DIR_CLEANUP )
3225            {
3226                std::cout << "VCI_MEM_CACHE ERROR " << name()
3227                          << " CLEANUP_DIR_WRITE state"
3228                          << " bad DIR allocation" << std::endl;
3229                exit(0);
3230            }
3231
3232            size_t way         = r_cleanup_way.read();
3233            size_t set         = m_y[(vci_addr_t)(r_cleanup_nline.read()*m_words*4)];
3234            bool cleanup_inst  = r_cleanup_trdid.read() & 0x1;
3235            bool match_srcid   = ((r_cleanup_copy.read() == r_cleanup_srcid.read())
[140]3236#if L1_MULTI_CACHE
3237                                and (r_cleanup_copy_cache.read() == r_cleanup_pktid.read())
3238#endif
3239                                );
[184]3240            bool match_inst    = (r_cleanup_copy_inst.read()  == cleanup_inst);
3241            bool match         = match_srcid && match_inst;
[2]3242
[184]3243            // update the cache directory (for the copies)
3244            DirectoryEntry entry;
3245            entry.valid   = true;
3246            entry.is_cnt  = r_cleanup_is_cnt.read();
3247            entry.dirty   = r_cleanup_dirty.read();
3248            entry.tag     = r_cleanup_tag.read();
3249            entry.lock    = r_cleanup_lock.read();
3250            entry.ptr     = r_cleanup_ptr.read();
3251
3252            if ( r_cleanup_is_cnt.read() )      // counter mode
3253            {
3254                entry.count  = r_cleanup_count.read() -1;
3255                entry.owner.srcid   = 0;
[140]3256#if L1_MULTI_CACHE
[184]3257                entry.owner.cache_id= 0;
[140]3258#endif
[184]3259                entry.owner.inst    = 0;
3260                // response to the cache
3261                r_cleanup_fsm = CLEANUP_RSP;
3262            }
3263            else                                            // linked_list mode
3264            {                       
3265                if ( match )  // hit
3266                {
3267                    entry.count         = 0; // no more copy
3268                    entry.owner.srcid   = 0;
[140]3269#if L1_MULTI_CACHE
[184]3270                    entry.owner.cache_id=0;
[140]3271#endif
[184]3272                    entry.owner.inst    = 0;
3273                    r_cleanup_fsm       = CLEANUP_RSP;
3274                }
3275                else         // miss
3276                {
3277                    entry.count          = r_cleanup_count.read();
3278                    entry.owner.srcid    = r_cleanup_copy.read();
[140]3279#if L1_MULTI_CACHE
[184]3280                    entry.owner.cache_id = r_cleanup_copy_cache.read();
[140]3281#endif
[184]3282                    entry.owner.inst     = r_cleanup_copy_inst.read();
3283                    r_cleanup_fsm        = CLEANUP_UPT_LOCK;
3284                }
[2]3285            }
[184]3286            m_cache_directory.write(set, way, entry); 
[2]3287
[184]3288#if DEBUG_MEMC_CLEANUP
3289if( m_debug_cleanup_fsm )
3290{
3291    std::cout << "  <MEMC.CLEANUP_DIR_WRITE> Update directory:" << std::hex
3292              << " line = " << r_cleanup_nline.read() * m_words * 4
3293              << " / dir_id = " << entry.owner.srcid
3294              << " / dir_ins = " << entry.owner.inst
3295              << " / count = " << entry.count
3296              << " / is_cnt = " << entry.is_cnt << std::endl;
3297}
3298#endif
3299
3300            break;
[2]3301        }
[184]3302        ///////////////////////
3303        case CLEANUP_HEAP_LOCK:  // two cases are handled in this state:
3304                                 // - the matching copy is directly in the directory
3305                                 // - the matching copy is the first copy in the heap
[2]3306        {
[184]3307            if ( r_alloc_heap_fsm.read() == ALLOC_HEAP_CLEANUP )
3308            {
3309                size_t way              = r_cleanup_way.read();
3310                size_t set              = m_y[(vci_addr_t)(r_cleanup_nline.read()*m_words*4)];
3311                HeapEntry heap_entry    = m_heap.read(r_cleanup_ptr.read());
3312                bool last               = (heap_entry.next == r_cleanup_ptr.read());
3313                bool cleanup_inst       = r_cleanup_trdid.read() & 0x1;
3314
3315                // match_dir computation
3316                bool match_dir_srcid    = (r_cleanup_copy.read() == r_cleanup_srcid.read());
3317                bool match_dir_inst     = (r_cleanup_copy_inst.read()  == cleanup_inst);
3318                bool match_dir          = match_dir_srcid and match_dir_inst;
[140]3319#if L1_MULTI_CACHE
[184]3320                match_dir = match_dir and (r_cleanup_copy_cache.read() == r_cleanup_pktid.read());
[140]3321#endif
[2]3322
[184]3323                // match_heap computation
3324                bool match_heap_srcid   = (heap_entry.owner.srcid == r_cleanup_srcid.read());
3325                bool match_heap_inst    = (heap_entry.owner.inst  == cleanup_inst);
3326                bool match_heap         = match_heap_srcid and match_heap_inst;
[140]3327#if L1_MULTI_CACHE
[184]3328                match_heap = match_heap and (heap_entry.owner.cache_id == r_cleanup_pktid.read());
[140]3329#endif
[2]3330
[184]3331                r_cleanup_prev_ptr      = r_cleanup_ptr.read();
3332                r_cleanup_prev_srcid    = heap_entry.owner.srcid;
[140]3333#if L1_MULTI_CACHE
[184]3334                r_cleanup_prev_cache_id = heap_entry.owner.cache_id;
[140]3335#endif
[184]3336                r_cleanup_prev_inst     = heap_entry.owner.inst;
[140]3337
[184]3338                if (match_dir) // the matching copy is registered in the directory
3339                {       
3340                    // the copy registered in the directory must be replaced
3341                    // by the first copy registered in the heap
3342                    // and the corresponding entry must be freed
3343                    DirectoryEntry dir_entry;
3344                    dir_entry.valid             = true;
3345                    dir_entry.is_cnt        = r_cleanup_is_cnt.read();
3346                    dir_entry.dirty             = r_cleanup_dirty.read();
3347                    dir_entry.tag               = r_cleanup_tag.read();
3348                    dir_entry.lock              = r_cleanup_lock.read();
3349                    dir_entry.ptr           = heap_entry.next;
3350                    dir_entry.count         = r_cleanup_count.read()-1;
3351                    dir_entry.owner.srcid   = heap_entry.owner.srcid;
[140]3352#if L1_MULTI_CACHE
[184]3353                    dir_entry.owner.cache_id = heap_entry.owner.cache_id;
[140]3354#endif
[184]3355                    dir_entry.owner.inst    = heap_entry.owner.inst;
3356                    m_cache_directory.write(set,way,dir_entry);
3357                    r_cleanup_next_ptr      = r_cleanup_ptr.read();
3358                    r_cleanup_fsm           = CLEANUP_HEAP_FREE;
3359                }
3360                else if (match_heap) // the matching copy is the first copy in the heap
3361                {
3362                    // The first copy in heap must be freed
3363                    // and the copy registered in directory must point to the next copy in heap
3364                    DirectoryEntry dir_entry;
3365                    dir_entry.valid             = true;
3366                    dir_entry.is_cnt        = r_cleanup_is_cnt.read();
3367                    dir_entry.dirty             = r_cleanup_dirty.read();
3368                    dir_entry.tag               = r_cleanup_tag.read();
3369                    dir_entry.lock              = r_cleanup_lock.read();
3370                    dir_entry.ptr           = heap_entry.next;
3371                    dir_entry.count         = r_cleanup_count.read()-1;
3372                    dir_entry.owner.srcid   = r_cleanup_copy.read();
[140]3373#if L1_MULTI_CACHE
[184]3374                    dir_entry.owner.cache_id = r_cleanup_copy_cache.read();
[140]3375#endif
[184]3376                    dir_entry.owner.inst    = r_cleanup_copy_inst.read();
3377                    m_cache_directory.write(set,way,dir_entry);
3378                    r_cleanup_next_ptr      = r_cleanup_ptr.read();
3379                    r_cleanup_fsm           = CLEANUP_HEAP_FREE;
3380                }
3381                else if(!last) // The matching copy is in the heap, but is not the first copy
3382                {
3383                    // The directory entry must be modified to decrement count
3384                    DirectoryEntry  dir_entry;
3385                    dir_entry.valid           = true;
3386                    dir_entry.is_cnt      = r_cleanup_is_cnt.read();
3387                    dir_entry.dirty           = r_cleanup_dirty.read();
3388                    dir_entry.tag             = r_cleanup_tag.read();
3389                    dir_entry.lock        = r_cleanup_lock.read();
3390                    dir_entry.ptr         = r_cleanup_ptr.read();
3391                    dir_entry.count       = r_cleanup_count.read()-1;
3392                    dir_entry.owner.srcid = r_cleanup_copy.read();
[140]3393#if L1_MULTI_CACHE
[184]3394                    dir_entry.owner.cache_id = r_cleanup_copy_cache.read();
[140]3395#endif
[184]3396                    dir_entry.owner.inst     = r_cleanup_copy_inst.read();
3397                    m_cache_directory.write(set,way,dir_entry);
3398                    r_cleanup_next_ptr       = heap_entry.next;
3399                    r_cleanup_fsm            = CLEANUP_HEAP_SEARCH;
3400                }
3401                else
3402                {
3403                    std::cout << "VCI_MEM_CACHE ERROR " << name()
3404                              << " CLEANUP_HEAP_LOCK state"
3405                              << " hit but copy not found" << std::endl;
3406                    exit(0);
3407                }
[2]3408
[184]3409#if DEBUG_MEMC_CLEANUP
3410if( m_debug_cleanup_fsm )
3411{
3412    std::cout << "  <MEMC.CLEANUP_HEAP_LOCK> Checks matching:"
3413              << " line = " << r_cleanup_nline.read() * m_words * 4
3414              << " / dir_id = " << r_cleanup_copy.read()
3415              << " / dir_ins = " << r_cleanup_copy_inst.read()
3416              << " / heap_id = " << heap_entry.owner.srcid
3417              << " / heap_ins = " << heap_entry.owner.inst
3418              << " / search_id = " << r_cleanup_srcid.read()
3419              << " / search_ins = " << (r_cleanup_trdid.read()&0x1) << std::endl;
3420}
3421#endif
[2]3422            }
[184]3423            break;
[2]3424        }
[184]3425        /////////////////////////
3426        case CLEANUP_HEAP_SEARCH:  // This state is handling the case where the copy
3427                                   // is in the heap, but is not the first in the linked list
[2]3428        {
[184]3429            if ( r_alloc_heap_fsm.read() != ALLOC_HEAP_CLEANUP )
3430            {
3431                std::cout << "VCI_MEM_CACHE ERROR " << name()
3432                          << " CLEANUP_HEAP_SEARCH state"
3433                          << " bad HEAP allocation" << std::endl;
3434                exit(0);
3435            }
3436
3437            HeapEntry heap_entry  = m_heap.read(r_cleanup_next_ptr.read());
3438            bool last             = (heap_entry.next == r_cleanup_next_ptr.read());
3439            bool cleanup_inst     = r_cleanup_trdid.read() & 0x1;
3440            bool match_heap_srcid = (heap_entry.owner.srcid == r_cleanup_srcid.read());
3441            bool match_heap_inst  = (heap_entry.owner.inst  == cleanup_inst);
3442            bool match_heap       = match_heap_srcid && match_heap_inst;
[140]3443#if L1_MULTI_CACHE
[184]3444            match_heap = match_heap and (heap_entry.owner.cache_id == r_cleanup_pktid.read());
[140]3445#endif
[2]3446
[184]3447#if DEBUG_MEMC_CLEANUP
3448if( m_debug_cleanup_fsm )
3449{
3450    std::cout << "  <MEMC.CLEANUP_HEAP_SEARCH> Cheks matching:"
3451              << " line = " << r_cleanup_nline.read() * m_words * 4
3452              << " / heap_id = " << heap_entry.owner.srcid
3453              << " / heap_ins = " << heap_entry.owner.inst
3454              << " / search_id = " << r_cleanup_srcid.read()
3455              << " / search_ins = " << (r_cleanup_trdid.read()&0x1)
3456              << " / last = " << last << std::endl;
3457}
3458#endif
3459            if(match_heap) // the matching copy must be removed
3460            {
3461                r_cleanup_ptr = heap_entry.next; // reuse ressources
3462                r_cleanup_fsm = CLEANUP_HEAP_CLEAN;
3463            }
3464            else
3465            {
3466                if ( last )
3467                {
3468                    std::cout << "VCI_MEM_CACHE_ERROR " << name()
3469                              << " CLEANUP_HEAP_SEARCH state"
3470                              << " cleanup hit but copy not found" << std::endl;
3471                    exit(0);
3472                }
3473                else // test the next in the linked list
3474                {
3475                    r_cleanup_prev_ptr      = r_cleanup_next_ptr.read();
3476                    r_cleanup_prev_srcid    = heap_entry.owner.srcid;
[140]3477#if L1_MULTI_CACHE
[184]3478                    r_cleanup_prev_cache_id = heap_entry.owner.cache_id;
[140]3479#endif
[184]3480                    r_cleanup_prev_inst     = heap_entry.owner.inst;
3481                    r_cleanup_next_ptr      = heap_entry.next;
3482                    r_cleanup_fsm           = CLEANUP_HEAP_SEARCH;
3483
3484#if DEBUG_MEMC_CLEANUP
3485if( m_debug_cleanup_fsm )
3486{
3487    std::cout << "  <MEMC.CLEANUP_HEAP_SEARCH> Matching copy not found, search next:"
3488              << " line = " << r_cleanup_nline.read() * m_words * 4
3489              << " / heap_id = " << heap_entry.owner.srcid
3490              << " / heap_ins = " << heap_entry.owner.inst
3491              << " / search_id = " << r_cleanup_srcid.read()
3492              << " / search_ins = " << (r_cleanup_trdid.read()&0x1) << std::endl;
3493}
3494#endif
3495                }
[2]3496            }
[184]3497            break;
[2]3498        }
[184]3499        ////////////////////////
3500        case CLEANUP_HEAP_CLEAN:  // remove a copy in the linked list
[2]3501        {
[184]3502            if ( r_alloc_heap_fsm.read() != ALLOC_HEAP_CLEANUP )
3503            {
3504                std::cout << "VCI_MEM_CACHE ERROR " << name()
3505                          << " CLEANUP_HEAP_CLEAN state"
3506                          << "Bad HEAP allocation" << std::endl;
3507                exit(0);
3508            }
3509
3510            bool last = (r_cleanup_next_ptr.read() == r_cleanup_ptr.read());
3511            HeapEntry heap_entry;
3512            heap_entry.owner.srcid    = r_cleanup_prev_srcid.read();
[140]3513#if L1_MULTI_CACHE
[184]3514            heap_entry.owner.cache_id = r_cleanup_prev_cache_id.read();
[140]3515#endif
[184]3516            heap_entry.owner.inst     = r_cleanup_prev_inst.read();
3517            if(last) // this is the last entry of the list of copies
3518            {
3519                heap_entry.next     = r_cleanup_prev_ptr.read();
3520            }
3521            else  // this is not the last entry
3522            {
3523                heap_entry.next     = r_cleanup_ptr.read();
3524            }
3525            m_heap.write(r_cleanup_prev_ptr.read(),heap_entry);
3526            r_cleanup_fsm = CLEANUP_HEAP_FREE;
3527
3528#if DEBUG_MEMC_CLEANUP
3529if( m_debug_cleanup_fsm )
3530{
3531    std::cout << "  <MEMC.CLEANUP_HEAP_SEARCH> Remove the copy in the linked list" << std::endl;
3532}
3533#endif
3534            break;
[2]3535        }
[184]3536        ///////////////////////
3537        case CLEANUP_HEAP_FREE:  // The heap entry pointed by r_cleanup_next_ptr is freed
3538                                 // and becomes the head of the list of free entries
[2]3539        {
[184]3540            if ( r_alloc_heap_fsm.read() != ALLOC_HEAP_CLEANUP )
3541            {
3542                std::cout << "VCI_MEM_CACHE ERROR " << name() << " CLEANUP_HEAP_CLEAN state" << std::endl;
3543                std::cout << "Bad HEAP allocation" << std::endl;
3544                exit(0);
3545            }
3546
3547            HeapEntry heap_entry;
3548            heap_entry.owner.srcid    = 0;
[140]3549#if L1_MULTI_CACHE
[184]3550            heap_entry.owner.cache_id = 0;
[140]3551#endif
[184]3552            heap_entry.owner.inst     = false;
3553
3554            if(m_heap.is_full()) heap_entry.next     = r_cleanup_next_ptr.read();
3555            else                           heap_entry.next     = m_heap.next_free_ptr();
3556            m_heap.write(r_cleanup_next_ptr.read(),heap_entry);
3557            m_heap.write_free_ptr(r_cleanup_next_ptr.read());
3558            m_heap.unset_full();
3559            r_cleanup_fsm = CLEANUP_RSP;
3560
3561#if DEBUG_MEMC_CLEANUP
3562if( m_debug_cleanup_fsm )
3563{
3564    std::cout << "  <MEMC.CLEANUP_HEAP_SEARCH> Update the list of free entries" << std::endl;
3565}
3566#endif
3567            break;
[2]3568        }
[184]3569        //////////////////////
3570        case CLEANUP_UPT_LOCK:
[2]3571        {
[184]3572            if ( r_alloc_upt_fsm.read() == ALLOC_UPT_CLEANUP )
3573            {
3574                size_t index = 0;
3575                bool hit_inval;
3576                hit_inval = m_update_tab.search_inval(r_cleanup_nline.read(),index);
3577
3578                if ( !hit_inval ) // no pending inval
3579                {
3580
3581#if DEBUG_MEMC_CLEANUP
3582if( m_debug_cleanup_fsm )
3583{
3584    std::cout << "  <MEMC.CLEANUP_UPT_LOCK> Unexpected cleanup with no corresponding UPT entry:"
3585              << " address = " << std::hex << (r_cleanup_nline.read()*4*m_words) << std::endl;
3586}
[2]3587#endif
[184]3588                    r_cleanup_fsm = CLEANUP_RSP;
3589                }
3590                else            // pending inval
3591                {
3592                    r_cleanup_write_srcid = m_update_tab.srcid(index);
3593                    r_cleanup_write_trdid = m_update_tab.trdid(index);
3594                    r_cleanup_write_pktid = m_update_tab.pktid(index);
3595                    r_cleanup_need_rsp    = m_update_tab.need_rsp(index);
3596                    r_cleanup_fsm = CLEANUP_UPT_WRITE;
3597                }
3598                r_cleanup_index.write(index) ;
[2]3599            }
[184]3600            break;
[2]3601        }
[184]3602        ///////////////////////
3603        case CLEANUP_UPT_WRITE:  // decrement response counter
[2]3604        {
[184]3605            size_t count = 0;
3606            m_update_tab.decrement(r_cleanup_index.read(), count);
3607            if ( count == 0 )
3608            {
3609                m_update_tab.clear(r_cleanup_index.read());
3610
3611#if DEBUG_MEMC_CLEANUP
3612if( m_debug_cleanup_fsm )
3613{
3614    std::cout << "  <MEMC.CLEANUP_UPT_WRITE> Decrement response counter in UPT:"
3615              << " UPT_index = " << r_cleanup_index.read()
3616              << " rsp_count = " << count << std::endl;
[57]3617}
[2]3618#endif
[184]3619                if( r_cleanup_need_rsp.read() ) r_cleanup_fsm = CLEANUP_WRITE_RSP ; 
3620                else                                        r_cleanup_fsm = CLEANUP_RSP;
3621            }
3622            else
3623            {
3624                r_cleanup_fsm = CLEANUP_RSP ;
[2]3625            }
[184]3626            break;
[2]3627        }
[184]3628        ///////////////////////
3629        case CLEANUP_WRITE_RSP: // Response to a previous write on the direct network
[2]3630        {
[184]3631            if( !r_cleanup_to_tgt_rsp_req.read() )
3632            {
3633                r_cleanup_to_tgt_rsp_req     = true;
3634                r_cleanup_to_tgt_rsp_srcid   = r_cleanup_write_srcid.read();
3635                r_cleanup_to_tgt_rsp_trdid   = r_cleanup_write_trdid.read();
3636                r_cleanup_to_tgt_rsp_pktid   = r_cleanup_write_pktid.read();
3637                r_cleanup_fsm                = CLEANUP_RSP;
3638
3639#if DEBUG_MEMC_CLEANUP
3640if( m_debug_cleanup_fsm )
3641{
3642    std::cout << "  <MEMC.CLEANUP_WRITE_RSP> Send a response to a cleanup request:"
3643              << " rsrcid = " << r_cleanup_write_srcid.read()
3644              << " / rtrdid = " << r_cleanup_write_trdid.read() << std::endl;
3645}
3646#endif
3647            }
3648            break;
[2]3649        }
3650        /////////////////
[184]3651        case CLEANUP_RSP:       // Response to a cleanup on the coherence network
[2]3652        {
[184]3653            if ( p_vci_tgt_cleanup.rspack.read() )
3654            {
3655                r_cleanup_fsm = CLEANUP_IDLE;
3656
3657#if DEBUG_MEMC_CLEANUP
3658if( m_debug_cleanup_fsm )
3659{
3660    std::cout << "  <MEMC.CLEANUP_RSP> Send the response to a cleanup request:"
3661              << " rsrcid = " << r_cleanup_write_srcid.read()
3662              << " / rtrdid = " << r_cleanup_write_trdid.read() << std::endl;
3663}
3664#endif
3665            }
3666            break;
[2]3667        }
3668    } // end switch cleanup fsm
3669
3670    ////////////////////////////////////////////////////////////////////////////////////
[184]3671    //          SC FSM
[2]3672    ////////////////////////////////////////////////////////////////////////////////////
[184]3673    // The SC FSM handles the SC (Store Conditionnal) atomic commands,
3674    // that are handled as "compare-and-swap instructions.
3675    //
3676    // This command contains two or four flits:
3677    // - In case of 32 bits atomic access, the first flit contains the value read
3678    // by a previous LL instruction, the second flit contains the value to be writen.
3679    // - In case of 64 bits atomic access, the 2 first flits contains the value read
3680    // by a previous LL instruction, the 2 next flits contains the value to be writen.
3681    //
3682    // The target address is cachable. If it is replicated in other L1 caches
3683    // than the writer, a coherence operation is done.
3684    //
[2]3685    // It access the directory to check hit / miss.
[184]3686    // - In case of miss, the SC FSM must register a GET transaction in TRT.
[2]3687    // If a read transaction to the XRAM for this line already exists,
[184]3688    // or if the transaction table is full, it goes to the WAIT state
3689    // to release the locks and try again. When the GET transaction has been
3690    // launched, it goes to the WAIT state and try again.
3691    // The SC request is not consumed in the FIFO until a HIT is obtained.
3692    // - In case of hit...
3693    ///////////////////////////////////////////////////////////////////////////////////
[2]3694
[184]3695    switch ( r_sc_fsm.read() )
3696    {
3697        /////////////
3698        case SC_IDLE:       // fill the local rdata buffers
3699        {
3700            if( m_cmd_sc_addr_fifo.rok() )
3701            {
[2]3702
[184]3703#if DEBUG_MEMC_SC
3704if( m_debug_sc_fsm )
3705{
3706    std::cout << "  <MEMC.SC_IDLE> SC command: " << std::hex
3707              << " srcid = " <<  m_cmd_sc_srcid_fifo.read()
3708              << " addr = " <<  m_cmd_sc_addr_fifo.read()
3709              << " wdata = " << m_cmd_sc_wdata_fifo.read()
3710              << " eop = " << m_cmd_sc_eop_fifo.read()
3711              << " cpt  = " << std::dec << r_sc_cpt.read() << std::endl;
[57]3712}
[2]3713#endif
[184]3714                if( m_cmd_sc_eop_fifo.read() )
3715                {
3716                    m_cpt_sc++;
3717                    r_sc_fsm = SC_DIR_LOCK;
3718                }
3719                else  // we keep the last word in the FIFO
3720                {
3721                    cmd_sc_fifo_get = true;
3722                }
3723                // We fill the two buffers
3724                if ( r_sc_cpt.read() < 2 ) // 32 bits access
3725                    r_sc_rdata[r_sc_cpt.read()] = m_cmd_sc_wdata_fifo.read();
3726
3727                if((r_sc_cpt.read() == 1) && m_cmd_sc_eop_fifo.read())
3728                    r_sc_wdata = m_cmd_sc_wdata_fifo.read();
3729
3730                if( r_sc_cpt.read()>3 ) // more than 4 flits...
3731                {
3732                    std::cout << "VCI_MEM_CACHE ERROR in SC_IDLE state : illegal SC command"
3733                              << std::endl;
3734                    exit(0);
3735                }
3736
3737                if ( r_sc_cpt.read()==2 )
3738                    r_sc_wdata = m_cmd_sc_wdata_fifo.read();
3739
3740                r_sc_cpt = r_sc_cpt.read()+1;
3741            }   
3742            break;
[2]3743        }
3744        /////////////////
[184]3745        case SC_DIR_LOCK:  // Read the directory
[2]3746        {
[184]3747            if( r_alloc_dir_fsm.read() == ALLOC_DIR_SC )
3748            {
3749                size_t way = 0;
3750                DirectoryEntry entry(m_cache_directory.read(m_cmd_sc_addr_fifo.read(), way));
3751
3752                r_sc_is_cnt     = entry.is_cnt;
3753                r_sc_dirty      = entry.dirty;
3754                r_sc_tag        = entry.tag;
3755                r_sc_way        = way;
3756                r_sc_copy       = entry.owner.srcid;
[140]3757#if L1_MULTI_CACHE
[184]3758                r_sc_copy_cache = entry.owner.cache_id;
[140]3759#endif
[184]3760                r_sc_copy_inst  = entry.owner.inst;
3761                r_sc_ptr        = entry.ptr;
3762                r_sc_count      = entry.count;
[140]3763
[184]3764                if ( entry.valid )      r_sc_fsm = SC_DIR_HIT_READ;
[200]3765                else                        r_sc_fsm = SC_MISS_TRT_LOCK;
[184]3766
3767#if DEBUG_MEMC_SC
3768if( m_debug_sc_fsm )
3769{
3770    std::cout << "  <MEMC.SC_DIR_LOCK> Directory acces"
3771              << " / address = " << m_cmd_sc_addr_fifo.read()
3772              << " / hit = " << entry.valid
3773              << " / count = " << entry.count
3774              << " / is_cnt = " << entry.is_cnt << std::endl;
3775}
3776#endif
[2]3777            }
[184]3778            break;
[2]3779        }
[184]3780        /////////////////////
3781        case SC_DIR_HIT_READ:  // update directory for lock and dirty bit
3782                               // and check data change in cache
[2]3783        {
[184]3784            size_t way  = r_sc_way.read();
3785            size_t set  = m_y[(vci_addr_t)(m_cmd_sc_addr_fifo.read())];
3786            size_t word = m_x[(vci_addr_t)(m_cmd_sc_addr_fifo.read())];
[2]3787
[184]3788            // update directory (lock & dirty bits)
3789            DirectoryEntry entry;
3790            entry.valid          = true;
3791            entry.is_cnt         = r_sc_is_cnt.read();
3792            entry.dirty          = true;
3793            entry.lock           = true;
3794            entry.tag            = r_sc_tag.read();
3795            entry.owner.srcid    = r_sc_copy.read();
[140]3796#if L1_MULTI_CACHE
[184]3797            entry.owner.cache_id = r_sc_copy_cache.read();
[140]3798#endif
[184]3799            entry.owner.inst     = r_sc_copy_inst.read();
3800            entry.count          = r_sc_count.read();
3801            entry.ptr            = r_sc_ptr.read();
[2]3802
[184]3803            m_cache_directory.write(set, way, entry);
[2]3804
[184]3805            // read data in cache & check data change
3806            bool ok = ( r_sc_rdata[0].read() == m_cache_data[way][set][word] );
3807            if ( r_sc_cpt.read()==4 )  // 64 bits SC
3808                ok &= ( r_sc_rdata[1] == m_cache_data[way][set][word+1] );
3809
3810            // to avoid livelock, force the atomic access to fail pseudo-randomly
3811            bool forced_fail = ( (r_sc_lfsr % (64) == 0) && RANDOMIZE_SC );
3812            r_sc_lfsr = (r_sc_lfsr >> 1) ^ ((-(r_sc_lfsr & 1)) & 0xd0000001);
3813
3814            if( ok and not forced_fail )        // no data change
3815            {
3816                r_sc_fsm = SC_DIR_HIT_WRITE;
3817            }
3818            else                            // return failure
3819            {
3820                r_sc_fsm = SC_RSP_FAIL;
3821            }
3822
3823#if DEBUG_MEMC_SC
3824if( m_debug_sc_fsm )
3825{
3826    std::cout << "  <MEMC.SC_DIR_HIT_READ> Test if SC success:"
3827              << " / expected value = " << r_sc_rdata[0].read()
3828              << " / actual value = " << m_cache_data[way][set][word]
3829              << " / forced_fail = " << forced_fail << std::endl;
[57]3830}
[2]3831#endif
[184]3832            break;
[2]3833        }
[200]3834        //////////////////////
[184]3835        case SC_DIR_HIT_WRITE:          // write data in the cache
3836                                    // and test if a coherence request is required
[2]3837        {
[184]3838            size_t way  = r_sc_way.read();
3839            size_t set  = m_y[(vci_addr_t)(m_cmd_sc_addr_fifo.read())];
3840            size_t word = m_x[(vci_addr_t)(m_cmd_sc_addr_fifo.read())];
[2]3841
[184]3842            // cache update
3843            m_cache_data[way][set][word] = r_sc_wdata.read();
3844            if(r_sc_cpt.read()==4)
3845                m_cache_data[way][set][word+1] = m_cmd_sc_wdata_fifo.read();
[2]3846         
[184]3847            // test coherence request
3848            if(r_sc_count.read())   // replicated line
3849            {
3850                if ( r_sc_is_cnt.read() )
3851                {
[200]3852                    r_sc_fsm = SC_BC_TRT_LOCK;          // broadcast invalidate required
[184]3853                }
3854                else if( !r_sc_to_init_cmd_multi_req.read() &&
3855                         !r_sc_to_init_cmd_brdcast_req.read()  )
3856                {
3857                    r_sc_fsm = SC_UPT_LOCK;                     // multi update required
3858                }
3859                else
3860                {
3861                    r_sc_fsm = SC_WAIT;
3862                }
3863            }
3864            else                    // no copies
3865            {
3866                r_sc_fsm = SC_RSP_SUCCESS;
3867            }
3868
3869#if DEBUG_MEMC_SC
3870if( m_debug_sc_fsm )
3871{
3872    std::cout << "  <MEMC.SC_DIR_HIT_WRITE> Update cache:"
3873              << " way = " << std::dec << way
3874              << " / set = " << set
3875              << " / word = " << word
3876              << " / value = " << r_sc_wdata.read()
3877              << " / count = " << r_sc_count.read() << std::endl;
3878}
3879#endif
3880            break;
[2]3881        }
[184]3882        /////////////////
3883        case SC_UPT_LOCK:  //  register the transaction in UPT
[2]3884        {
[184]3885            if ( r_alloc_upt_fsm.read() == ALLOC_UPT_SC )
3886            {
3887                bool        wok        = false;
3888                size_t      index      = 0;
3889                size_t      srcid      = m_cmd_sc_srcid_fifo.read();
3890                size_t      trdid      = m_cmd_sc_trdid_fifo.read();
3891                size_t      pktid      = m_cmd_sc_pktid_fifo.read();
3892                addr_t      nline      = m_nline[(vci_addr_t)(m_cmd_sc_addr_fifo.read())];
3893                size_t      nb_copies  = r_sc_count.read();
[2]3894
[184]3895                wok = m_update_tab.set(true,    // it's an update transaction
3896                                       false,   // it's not a broadcast
3897                                       true,    // it needs a response
3898                                       srcid,
3899                                       trdid,
3900                                       pktid,
3901                                       nline,
3902                                       nb_copies,
3903                                       index);
3904                if (wok)  // coherence transaction registered in UPT
3905                {
3906                    r_sc_upt_index = index;
[200]3907                    r_sc_fsm = SC_UPT_HEAP_LOCK;
[184]3908                }
3909                else       //  releases the locks protecting UPT and DIR if no entry
3910                {
3911                    r_sc_fsm = SC_WAIT;
3912                }
[2]3913
[184]3914#if DEBUG_MEMC_SC
3915if( m_debug_sc_fsm )
3916{
3917    std::cout << "  <MEMC.SC_UPT_LOCK> Register multi-update transaction in UPT" 
3918              << " / wok = " << wok
3919              << " / nline  = " << std::hex << nline
3920              << " / count = " << nb_copies << std::endl;
[57]3921}
[2]3922#endif
[184]3923            }
3924            break;
[2]3925        }
[184]3926        /////////////
3927        case SC_WAIT:   // release all locks and retry from beginning
[2]3928        {
[184]3929
3930#if DEBUG_MEMC_SC
3931if( m_debug_sc_fsm )
3932{
3933    std::cout << "  <MEMC.SC_WAIT> Release all locks" << std::endl;
3934}
3935#endif
3936            r_sc_fsm = SC_DIR_LOCK;
3937            break;
[2]3938        }
[184]3939        //////////////////
[200]3940        case SC_UPT_HEAP_LOCK:  // lock the heap
[2]3941        {
[184]3942            if( r_alloc_heap_fsm.read() == ALLOC_HEAP_SC )
3943            {
3944
3945#if DEBUG_MEMC_SC
3946if( m_debug_sc_fsm )
3947{
[200]3948    std::cout << "  <MEMC.SC_UPT_HEAP_LOCK> Get access to the heap" << std::endl;
[184]3949}
3950#endif
3951                r_sc_fsm = SC_UPT_REQ;
3952            }
3953            break;
[2]3954        }
[184]3955        ////////////////
3956        case SC_UPT_REQ:        // send a first update request to INIT_CMD FSM
[2]3957        {
[184]3958            assert((r_alloc_heap_fsm.read() == ALLOC_HEAP_SC) and
3959                   "VCI_MEM_CACHE ERROR : bad HEAP allocation");
[2]3960
[184]3961            if( !r_sc_to_init_cmd_multi_req.read() && !r_sc_to_init_cmd_brdcast_req.read() )
3962            {
3963                r_sc_to_init_cmd_brdcast_req  = false;
3964                r_sc_to_init_cmd_trdid        = r_sc_upt_index.read();
3965                r_sc_to_init_cmd_nline        = m_nline[(vci_addr_t)(m_cmd_sc_addr_fifo.read())];
3966                r_sc_to_init_cmd_index        = m_x[(vci_addr_t)(m_cmd_sc_addr_fifo.read())];
3967                r_sc_to_init_cmd_wdata        = r_sc_wdata.read();
3968
3969                if(r_sc_cpt.read() == 4)
3970                {
3971                    r_sc_to_init_cmd_is_long    = true;
3972                    r_sc_to_init_cmd_wdata_high = m_cmd_sc_wdata_fifo.read();
3973                }
3974                else
3975                {
3976                    r_sc_to_init_cmd_is_long    = false;
3977                    r_sc_to_init_cmd_wdata_high = 0;
3978                }
3979
3980                // We put the first copy in the fifo
3981                sc_to_init_cmd_fifo_put     = true;
3982                sc_to_init_cmd_fifo_inst    = r_sc_copy_inst.read();
3983                sc_to_init_cmd_fifo_srcid   = r_sc_copy.read();
[140]3984#if L1_MULTI_CACHE
[184]3985                sc_to_init_cmd_fifo_cache_id= r_sc_copy_cache.read();
[140]3986#endif
[184]3987                if(r_sc_count.read() == 1) // one single copy
3988                {
3989                    r_sc_fsm = SC_IDLE;   // Response will be sent after receiving
3990                                            // update responses
3991                    cmd_sc_fifo_get            = true;
3992                    r_sc_to_init_cmd_multi_req = true;
3993                    r_sc_cpt = 0;
3994                }
3995                else                    // several copies
3996                {
3997                    r_sc_fsm = SC_UPT_NEXT;
3998                }
3999
4000#if DEBUG_MEMC_SC
4001if( m_debug_sc_fsm )
4002{
4003    std::cout << "  <MEMC.SC_UPT_REQ> Send the first update request to INIT_CMD FSM "
4004              << " / address = " << std::hex << m_cmd_sc_addr_fifo.read()
4005              << " / wdata = " << std::hex << r_sc_wdata.read()
4006              << " / srcid = " << std::hex << r_sc_copy.read()
4007              << " / inst = " << r_sc_copy_inst.read() << std::endl;
[57]4008}
[2]4009#endif
4010            }
[184]4011            break;
[2]4012        }
[184]4013        /////////////////
4014        case SC_UPT_NEXT:       // send a multi-update request to INIT_CMD FSM
[2]4015        {
[184]4016            assert((r_alloc_heap_fsm.read() == ALLOC_HEAP_SC)
4017                 and "VCI_MEM_CACHE ERROR : bad HEAP allocation");
4018
4019            HeapEntry entry = m_heap.read(r_sc_ptr.read());
4020            sc_to_init_cmd_fifo_srcid    = entry.owner.srcid;
[140]4021#if L1_MULTI_CACHE
[184]4022            sc_to_init_cmd_fifo_cache_id = entry.owner.cache_id;
[140]4023#endif
[184]4024            sc_to_init_cmd_fifo_inst     = entry.owner.inst;
4025            sc_to_init_cmd_fifo_put = true;
[2]4026
[184]4027            if( m_sc_to_init_cmd_inst_fifo.wok() ) // request accepted by INIT_CMD FSM
4028            {
4029                r_sc_ptr = entry.next;
4030                if( entry.next == r_sc_ptr.read() )  // last copy
4031                {
4032                    r_sc_to_init_cmd_multi_req = true;
4033                    r_sc_fsm = SC_IDLE;   // Response will be sent after receiving
4034                                            // all update responses
4035                    cmd_sc_fifo_get = true;
4036                    r_sc_cpt        = 0;
4037                }
4038            }
4039
4040#if DEBUG_MEMC_SC
4041if( m_debug_sc_fsm )
4042{
4043    std::cout << "  <MEMC.SC_UPT_NEXT> Send the next update request to INIT_CMD FSM "
4044              << " / address = " << std::hex << m_cmd_sc_addr_fifo.read()
4045              << " / wdata = " << std::hex << r_sc_wdata.read()
4046              << " / srcid = " << std::hex << entry.owner.srcid
4047              << " / inst = " << entry.owner.inst << std::endl;
4048}
4049#endif
4050            break;
[2]4051        }
[184]4052        /////////////////////
[200]4053        case SC_BC_TRT_LOCK:            // check the TRT to register a PUT transaction     
[2]4054        {
[184]4055            if( r_alloc_trt_fsm.read() == ALLOC_TRT_SC )
4056            {
4057                if( !r_sc_to_ixr_cmd_req )  // we can transfer the request to IXR_CMD FSM
4058                {
4059                    // fill the data buffer
4060                    size_t way  = r_sc_way.read();
4061                    size_t set  = m_y[(vci_addr_t)(m_cmd_sc_addr_fifo.read())];
4062                        size_t word = m_x[(vci_addr_t)(m_cmd_sc_addr_fifo.read())];
4063                    for(size_t i = 0; i<m_words; i++)
4064                    {
4065                        if (i == word)
4066                        {
4067                            r_sc_to_ixr_cmd_data[i] = r_sc_wdata.read();
4068                        }
4069                        else if ( (i == word+1) && (r_sc_cpt.read()==4) ) // 64 bit SC
4070                        {
4071                            r_sc_to_ixr_cmd_data[i] = m_cmd_sc_wdata_fifo.read();
4072                        }
4073                        else
4074                        {
4075                            r_sc_to_ixr_cmd_data[i] = m_cache_data[way][set][i];
4076                        }
[2]4077                    }
[184]4078                    size_t wok_index = 0;
4079                    bool   wok       = !m_transaction_tab.full(wok_index);
4080                    if ( wok ) 
4081                    {
4082                        r_sc_trt_index = wok_index;
[200]4083                        r_sc_fsm       = SC_BC_UPT_LOCK;
[184]4084                    }
4085                    else
4086                    {
4087                        r_sc_fsm       = SC_WAIT;
4088                    }
4089                }
4090                else
4091                {
4092                    r_sc_fsm = SC_WAIT;
[2]4093                }
4094            }
[184]4095            break;
[2]4096        }
[184]4097        ///////////////////
[200]4098        case SC_BC_UPT_LOCK:  // Register a broadcast inval transaction in UPT
[2]4099        {
[184]4100            if ( r_alloc_upt_fsm.read() == ALLOC_UPT_SC )
4101            {
4102                bool        wok       = false;
4103                size_t      index     = 0;
4104                size_t      srcid     = m_cmd_sc_srcid_fifo.read();
4105                size_t      trdid     = m_cmd_sc_trdid_fifo.read();
4106                size_t      pktid     = m_cmd_sc_pktid_fifo.read();
4107                addr_t      nline     = m_nline[(vci_addr_t)(m_cmd_sc_addr_fifo.read())];
4108                size_t      nb_copies = r_sc_count.read();
[2]4109
[184]4110                // register a broadcast inval transaction in UPT
4111                wok = m_update_tab.set(false,   // it's an inval transaction
4112                                       true,    // it's a broadcast
4113                                       true,    // it needs a response
4114                                       srcid,
4115                                       trdid,
4116                                       pktid,
4117                                       nline,
4118                                       nb_copies,
4119                                       index);
4120               
4121                if ( wok )      // UPT not full
4122                {
4123                    r_sc_upt_index = index;
[200]4124                    r_sc_fsm = SC_BC_DIR_INVAL;
[184]4125#if DEBUG_MEMC_SC
4126if( m_debug_sc_fsm )
4127{
[200]4128    std::cout << "  <MEMC.SC_BC_UPT_LOCK> Register a broadcast inval transaction in UPT"
[184]4129              << " / nline = " << nline
4130              << " / count = " << nb_copies
4131              << " / upt_index = " << index << std::endl;
[57]4132}
[2]4133#endif
[184]4134                }
4135                else      //  releases the lock protecting UPT
4136                {
4137                     r_sc_fsm = SC_WAIT;
4138                }
4139            }
4140            break;
[2]4141        }
4142        //////////////////
[200]4143        case SC_BC_DIR_INVAL:  // Register the PUT transaction in TRT, and inval the DIR entry
[2]4144        {
[184]4145            if ( (r_alloc_trt_fsm.read() == ALLOC_TRT_SC ) &&
4146                 (r_alloc_upt_fsm.read() == ALLOC_UPT_SC ) &&
4147                 (r_alloc_dir_fsm.read() == ALLOC_DIR_SC ))
4148            {
4149                // set TRT
4150                m_transaction_tab.set(r_sc_trt_index.read(),
4151                                      false,            // PUT request to XRAM
4152                                      m_nline[(vci_addr_t)(m_cmd_sc_addr_fifo.read())],
4153                                      0,
4154                                      0,
4155                                      0,
4156                                      false,            // not a processor read
4157                                      0,               
4158                                      0,
4159                                      std::vector<be_t>(m_words,0),
4160                                      std::vector<data_t>(m_words,0));
[2]4161
[184]4162                // invalidate directory entry
4163                DirectoryEntry entry;
4164                entry.valid             = false;
4165                entry.dirty             = false;
4166                entry.tag               = 0;
4167                entry.is_cnt        = false;
4168                entry.lock              = false;
4169                entry.count         = 0;
4170                entry.owner.srcid   = 0;
[140]4171#if L1_MULTI_CACHE
[184]4172                entry.owner.cache_id= 0;
[140]4173#endif
[184]4174                entry.owner.inst    = false;
4175                entry.ptr           = 0;
4176                size_t set              = m_y[(vci_addr_t)(m_cmd_sc_addr_fifo.read())];
4177                size_t way              = r_sc_way.read();
4178                m_cache_directory.write(set, way, entry);
[2]4179
[200]4180                r_sc_fsm = SC_BC_CC_SEND;
[2]4181
[184]4182#if DEBUG_MEMC_SC
4183if( m_debug_sc_fsm )
4184{
[200]4185    std::cout << "  <MEMC.SC_BC_DIR_INVAL> Register the PUT in TRT and invalidate DIR entry"
[184]4186              << " / nline = " << std::hex << m_nline[(vci_addr_t)(m_cmd_sc_addr_fifo.read())]
4187              << " / set = " << std::dec << set << " / way = " << way << std::endl;
4188}
4189#endif
4190            }
4191            else
4192            {
[200]4193                assert(false and "LOCK ERROR in SC_FSM, STATE = SC_BC_DIR_INVAL");
[184]4194            }
4195            break;
[2]4196        }
[200]4197        ///////////////////
4198        case SC_BC_CC_SEND:  // Request the broadcast inval to INIT_CMD FSM
[2]4199        {
[184]4200            if ( !r_sc_to_init_cmd_multi_req.read() &&
4201                 !r_sc_to_init_cmd_brdcast_req.read())
4202            {
4203                r_sc_to_init_cmd_multi_req    = false;
4204                r_sc_to_init_cmd_brdcast_req  = true;
4205                r_sc_to_init_cmd_trdid        = r_sc_upt_index.read();
4206                r_sc_to_init_cmd_nline        = m_nline[(vci_addr_t)(m_cmd_sc_addr_fifo.read())];
4207                r_sc_to_init_cmd_index        = 0;
4208                r_sc_to_init_cmd_wdata        = 0;
[2]4209
[200]4210                r_sc_fsm = SC_BC_XRAM_REQ;
[184]4211            }
4212            break;
[2]4213        }
[184]4214        ////////////////////
[200]4215        case SC_BC_XRAM_REQ: // request the IXR FSM to start a put transaction
[2]4216        {
[184]4217            if ( !r_sc_to_ixr_cmd_req )
4218            {
4219                r_sc_to_ixr_cmd_req     = true;
4220                r_sc_to_ixr_cmd_write   = true;
4221                r_sc_to_ixr_cmd_nline   = m_nline[(vci_addr_t)(m_cmd_sc_addr_fifo.read())];
4222                r_sc_to_ixr_cmd_trdid   = r_sc_trt_index.read();
4223                r_sc_fsm                = SC_IDLE;
4224                cmd_sc_fifo_get         = true;
4225                r_sc_cpt                = 0;
4226
4227#if DEBUG_MEMC_SC
4228if( m_debug_sc_fsm )
4229{
[200]4230    std::cout << "  <MEMC.SC_BC_XRAM_REQ> Request a PUT transaction to IXR_CMD FSM" << std::hex
[184]4231              << " / nline = " << m_nline[(vci_addr_t)m_cmd_sc_addr_fifo.read()]
4232              << " / trt_index = " << r_sc_trt_index.read() << std::endl;
4233}
4234#endif
4235            }
4236            else
4237            {
[200]4238               std::cout << "MEM_CACHE, SC_BC_XRAM_REQ state : request should not have been previously set"
[184]4239                         << std::endl;
4240            }
4241            break;
[2]4242        }
[184]4243        /////////////////
4244        case SC_RSP_FAIL:  // request TGT_RSP FSM to send a failure response
[2]4245        {
[184]4246            if( !r_sc_to_tgt_rsp_req )
4247            {
4248                cmd_sc_fifo_get     = true;
4249                r_sc_cpt              = 0;
4250                r_sc_to_tgt_rsp_req     = true;
4251                r_sc_to_tgt_rsp_data    = 1;
4252                r_sc_to_tgt_rsp_srcid   = m_cmd_sc_srcid_fifo.read();
4253                r_sc_to_tgt_rsp_trdid   = m_cmd_sc_trdid_fifo.read();
4254                r_sc_to_tgt_rsp_pktid   = m_cmd_sc_pktid_fifo.read();
4255                r_sc_fsm              = SC_IDLE;
4256
4257#if DEBUG_MEMC_SC
4258if( m_debug_sc_fsm )
4259{
4260    std::cout << "  <MEMC.SC_RSP_FAIL> Request TGT_RSP to send a failure response" << std::endl;
4261}
4262#endif
4263            }
4264            break;
[2]4265        }
[184]4266        ////////////////////
4267        case SC_RSP_SUCCESS:  // request TGT_RSP FSM to send a success response
[2]4268        {
[184]4269            if( !r_sc_to_tgt_rsp_req )
4270            {
4271                cmd_sc_fifo_get       = true;
4272                r_sc_cpt              = 0;
4273                r_sc_to_tgt_rsp_req     = true;
4274                r_sc_to_tgt_rsp_data    = 0;
4275                r_sc_to_tgt_rsp_srcid   = m_cmd_sc_srcid_fifo.read();
4276                r_sc_to_tgt_rsp_trdid   = m_cmd_sc_trdid_fifo.read();
4277                r_sc_to_tgt_rsp_pktid   = m_cmd_sc_pktid_fifo.read();
4278                r_sc_fsm              = SC_IDLE;
4279
4280#if DEBUG_MEMC_SC
4281if( m_debug_sc_fsm )
4282{
4283    std::cout << "  <MEMC.SC_RSP_SUCCESS> Request TGT_RSP to send a success response" << std::endl;
4284}
4285#endif
4286            }
4287            break;
[2]4288        }
[184]4289        /////////////////////
[200]4290        case SC_MISS_TRT_LOCK:         // cache miss : request access to transaction Table
[2]4291        {
[184]4292            if( r_alloc_trt_fsm.read() == ALLOC_TRT_SC )
4293            {
4294                size_t   index = 0;
4295                bool hit_read = m_transaction_tab.hit_read(
4296                                  m_nline[(vci_addr_t)m_cmd_sc_addr_fifo.read()],index);
4297                bool hit_write = m_transaction_tab.hit_write(
4298                                   m_nline[(vci_addr_t)m_cmd_sc_addr_fifo.read()]);
4299                bool wok = !m_transaction_tab.full(index);
[2]4300
[184]4301#if DEBUG_MEMC_SC
4302if( m_debug_sc_fsm )
4303{
[200]4304    std::cout << "  <MEMC.SC_MISS_TRT_LOCK> Check TRT state"
[184]4305              << " / hit_read = "  << hit_read
4306              << " / hit_write = " << hit_write
4307              << " / wok = " << wok 
4308              << " / index = " << index << std::endl;
4309}
4310#endif
4311
4312                if ( hit_read || !wok || hit_write ) // missing line already requested or no space in TRT
4313                {
4314                    r_sc_fsm = SC_WAIT;
4315                }
4316                else
4317                {
4318                    r_sc_trt_index = index;
[200]4319                    r_sc_fsm       = SC_MISS_TRT_SET;
[184]4320                }
[2]4321            }
[184]4322            break;
[2]4323        }
[184]4324        ////////////////////
[200]4325        case SC_MISS_TRT_SET:   // register the GET transaction in TRT
[2]4326        {
[184]4327            if( r_alloc_trt_fsm.read() == ALLOC_TRT_SC )
4328            {
[2]4329                std::vector<be_t> be_vector;
4330                std::vector<data_t> data_vector;
4331                be_vector.clear();
4332                data_vector.clear();
4333                for ( size_t i=0; i<m_words; i++ )
4334                {   
4335                    be_vector.push_back(0);
4336                    data_vector.push_back(0);
4337                }
4338
[184]4339                m_transaction_tab.set(r_sc_trt_index.read(),
4340                                      true,             // read request         
4341                                      m_nline[(vci_addr_t)m_cmd_sc_addr_fifo.read()],
4342                                      m_cmd_sc_srcid_fifo.read(),
4343                                      m_cmd_sc_trdid_fifo.read(),
4344                                      m_cmd_sc_pktid_fifo.read(),
4345                                      false,            // write request from processor
4346                                      0,
4347                                      0,
4348                                      be_vector,
4349                                      data_vector);
[200]4350                r_sc_fsm = SC_MISS_XRAM_REQ;       
[184]4351
4352#if DEBUG_MEMC_SC
4353if( m_debug_sc_fsm )
4354{
[200]4355    std::cout << "  <MEMC.SC_MISS_TRT_SET> Register a GET transaction in TRT" << std::hex
[184]4356              << " / nline = " << m_nline[(vci_addr_t)m_cmd_sc_addr_fifo.read()]
4357              << " / trt_index = " << r_sc_trt_index.read() << std::endl;
[57]4358}
[2]4359#endif
[184]4360            }
4361            break;
[2]4362        }
[200]4363        //////////////////////
4364        case SC_MISS_XRAM_REQ:  // request the IXR_CMD FSM to fetch the missing line
[2]4365        {
[184]4366            if ( !r_sc_to_ixr_cmd_req )
4367            {
4368                r_sc_to_ixr_cmd_req        = true;
4369                r_sc_to_ixr_cmd_write      = false;
4370                r_sc_to_ixr_cmd_trdid      = r_sc_trt_index.read();
4371                r_sc_to_ixr_cmd_nline      = m_nline[(vci_addr_t)m_cmd_sc_addr_fifo.read()];
4372                r_sc_fsm                   = SC_WAIT;
4373
4374#if DEBUG_MEMC_SC
4375if( m_debug_sc_fsm )
4376{
[200]4377    std::cout << "  <MEMC.SC_MISS_XRAM_REQ> Request a GET transaction to IXR_CMD FSM" << std::hex
[184]4378              << " / nline = " << m_nline[(vci_addr_t)m_cmd_sc_addr_fifo.read()]
4379              << " / trt_index = " << r_sc_trt_index.read() << std::endl;
4380}
4381#endif
4382            }
4383            break;
[2]4384        }
[184]4385    } // end switch r_sc_fsm
[2]4386
4387
4388    //////////////////////////////////////////////////////////////////////////////
4389    //          INIT_CMD FSM
4390    //////////////////////////////////////////////////////////////////////////////
[200]4391    // The INIT_CMD fsm controls the VCI CMD initiator port on the coherence
4392    // network, used to update or invalidate cache lines in L1 caches.
[184]4393    //
4394    // It implements a round-robin priority between the three possible client FSMs
4395    // XRAM_RSP, WRITE and SC. Each FSM can request two types of services:
4396    // - r_xram_rsp_to_init_cmd_multi_req : multi-inval 
4397    //   r_xram_rsp_to_init_cmd_brdcast_req : broadcast-inval 
4398    // - r_write_to_init_cmd_multi_req : multi-update 
4399    //   r_write_to_init_cmd_brdcast_req : broadcast-inval
4400    // - r_sc_to_init_cmd_multi_req : multi-update 
4401    //   r_sc_to_init_cmd_brdcast_req : broadcast-inval
4402    //
4403    // An inval request is a single cell VCI write command containing the
[2]4404    // index of the line to be invalidated.
[184]4405    // An update request is a multi-cells VCI write command : The first cell
[2]4406    // contains the index of the cache line to be updated. The second cell contains
4407    // the index of the first modified word in the line. The following cells
4408    // contain the data.
4409    ///////////////////////////////////////////////////////////////////////////////
4410
[184]4411    switch ( r_init_cmd_fsm.read() )
4412    {
4413        ////////////////////////
4414        case INIT_CMD_UPDT_IDLE:        // XRAM_RSP FSM has highest priority
[2]4415        {
[184]4416            if ( m_xram_rsp_to_init_cmd_inst_fifo.rok() ||
4417                 r_xram_rsp_to_init_cmd_multi_req.read()  )
4418            {
4419                r_init_cmd_fsm = INIT_CMD_INVAL_NLINE;
4420                m_cpt_inval++;
4421            }
4422            else if ( r_xram_rsp_to_init_cmd_brdcast_req.read() )
4423            {
4424                r_init_cmd_fsm = INIT_CMD_XRAM_BRDCAST;
4425                m_cpt_inval++;
4426            }
4427            else if ( m_write_to_init_cmd_inst_fifo.rok() ||
4428                      r_write_to_init_cmd_multi_req.read() )
4429            {
4430                r_init_cmd_fsm = INIT_CMD_UPDT_NLINE;
4431                m_cpt_update++;
4432            }
4433            else if ( r_write_to_init_cmd_brdcast_req.read() )
4434            {
4435                r_init_cmd_fsm = INIT_CMD_WRITE_BRDCAST;
4436                m_cpt_inval++;
4437            }
4438            else if ( m_sc_to_init_cmd_inst_fifo.rok() ||
4439                      r_sc_to_init_cmd_multi_req.read()  )
4440            {
4441                r_init_cmd_fsm = INIT_CMD_SC_UPDT_NLINE;
4442                m_cpt_update++;
4443            }
4444            else if( r_sc_to_init_cmd_brdcast_req.read() )
4445            {
4446                r_init_cmd_fsm = INIT_CMD_SC_BRDCAST;
4447                m_cpt_inval++;
4448            }
4449            break;
[2]4450        }
4451        /////////////////////////
[184]4452        case INIT_CMD_INVAL_IDLE:       // WRITE FSM has highest priority
[2]4453        {
[184]4454            if ( m_write_to_init_cmd_inst_fifo.rok() ||
4455                 r_write_to_init_cmd_multi_req.read() )
4456            {
4457                r_init_cmd_fsm = INIT_CMD_UPDT_NLINE;
4458                m_cpt_update++;
4459            }
4460            else if ( r_write_to_init_cmd_brdcast_req.read() )
4461            {
4462                r_init_cmd_fsm = INIT_CMD_WRITE_BRDCAST;
4463                m_cpt_inval++;
4464            }
4465            else if ( m_sc_to_init_cmd_inst_fifo.rok() ||
4466                      r_sc_to_init_cmd_multi_req.read()  )
4467            {
4468                r_init_cmd_fsm = INIT_CMD_SC_UPDT_NLINE;
4469                m_cpt_update++;
4470            }
4471            else if( r_sc_to_init_cmd_brdcast_req.read() )
4472            {
4473                r_init_cmd_fsm = INIT_CMD_SC_BRDCAST;
4474                m_cpt_inval++;
4475            }
4476            else if ( m_xram_rsp_to_init_cmd_inst_fifo.rok() ||
4477                      r_xram_rsp_to_init_cmd_multi_req.read()  )
4478            {
4479                r_init_cmd_fsm = INIT_CMD_INVAL_NLINE;
4480                m_cpt_inval++;
4481            }
4482            else if ( r_xram_rsp_to_init_cmd_brdcast_req.read() )
4483            {
4484                r_init_cmd_fsm = INIT_CMD_XRAM_BRDCAST;
4485                m_cpt_inval++;
4486            }
4487            break;
[2]4488        }
[184]4489        //////////////////////////
4490        case INIT_CMD_SC_UPDT_IDLE:     // SC FSM has highest priority
[2]4491        {
[184]4492            if ( m_sc_to_init_cmd_inst_fifo.rok() ||
4493                 r_sc_to_init_cmd_multi_req.read()  )
4494            {
4495                r_init_cmd_fsm = INIT_CMD_SC_UPDT_NLINE;
4496                m_cpt_update++;
4497            }
4498            else if( r_sc_to_init_cmd_brdcast_req.read() )
4499            {
4500                r_init_cmd_fsm = INIT_CMD_SC_BRDCAST;
4501                m_cpt_inval++;
4502            }
4503            else if ( m_xram_rsp_to_init_cmd_inst_fifo.rok() ||
4504                      r_xram_rsp_to_init_cmd_multi_req.read()  )
4505            {
4506                r_init_cmd_fsm = INIT_CMD_INVAL_NLINE;
4507                m_cpt_inval++;
4508            }
4509            else if ( r_xram_rsp_to_init_cmd_brdcast_req.read() )
4510            {
4511                r_init_cmd_fsm = INIT_CMD_XRAM_BRDCAST;
4512                m_cpt_inval++;
4513            }
4514            else if ( m_write_to_init_cmd_inst_fifo.rok() ||
4515                      r_write_to_init_cmd_multi_req.read() )
4516            {
4517                r_init_cmd_fsm = INIT_CMD_UPDT_NLINE;
4518                m_cpt_update++;
4519            }
4520            else if ( r_write_to_init_cmd_brdcast_req.read() )
4521            {
4522                r_init_cmd_fsm = INIT_CMD_WRITE_BRDCAST;
4523                m_cpt_inval++;
4524            }
4525            break;
[2]4526        }
[184]4527        //////////////////////////
4528        case INIT_CMD_INVAL_NLINE:      // send a multi-inval (from XRAM_RSP)
[2]4529        {
[184]4530            if ( m_xram_rsp_to_init_cmd_inst_fifo.rok() )
4531            {
4532                if ( p_vci_ini.cmdack )
4533                {
4534                    m_cpt_inval_mult++;
4535                    r_init_cmd_fsm = INIT_CMD_INVAL_NLINE;
4536                    xram_rsp_to_init_cmd_fifo_get = true;
4537                }
4538            }
4539            else
4540            {
4541                if( r_xram_rsp_to_init_cmd_multi_req.read() ) r_xram_rsp_to_init_cmd_multi_req = false;
4542                r_init_cmd_fsm = INIT_CMD_INVAL_IDLE;
[2]4543            }
[184]4544            break;
[2]4545        }
[184]4546        ///////////////////////////
4547        case INIT_CMD_XRAM_BRDCAST:     // send a broadcast-inval (from XRAM_RSP)
[2]4548        {
[184]4549            if ( p_vci_ini.cmdack )
4550            {
4551                m_cpt_inval_brdcast++;
4552                r_init_cmd_fsm = INIT_CMD_INVAL_IDLE;
4553                r_xram_rsp_to_init_cmd_brdcast_req = false;
4554            }
4555            break;
[2]4556        }
[184]4557        ////////////////////////////
4558        case INIT_CMD_WRITE_BRDCAST:    // send a broadcast-inval (from WRITE FSM)
[2]4559        {
[184]4560            if( p_vci_ini.cmdack )
4561            {
4562
4563#if DEBUG_MEMC_INIT_CMD
4564if( m_debug_init_cmd_fsm )
4565{
4566    std::cout << "  <MEMC.INIT_CMD_WRITE_BRDCAST> Broadcast-Inval for line "
4567              << r_write_to_init_cmd_nline.read() << std::endl;
4568}
4569#endif
4570                m_cpt_inval_brdcast++;
4571                r_write_to_init_cmd_brdcast_req = false;
4572                r_init_cmd_fsm = INIT_CMD_UPDT_IDLE;
4573            }
4574            break;
[2]4575        }
4576        /////////////////////////
[184]4577        case INIT_CMD_UPDT_NLINE:  // send nline for a multi-update (from WRITE FSM)
[2]4578        {
[184]4579            if ( m_write_to_init_cmd_inst_fifo.rok() )
4580            {
4581                if ( p_vci_ini.cmdack )
4582                {
4583                    m_cpt_update_mult++;
4584                    r_init_cmd_fsm = INIT_CMD_UPDT_INDEX;
4585                    // write_to_init_cmd_fifo_get = true;
4586                }
4587            }
4588            else
4589            {
4590                if ( r_write_to_init_cmd_multi_req.read() ) r_write_to_init_cmd_multi_req = false;
4591                r_init_cmd_fsm = INIT_CMD_UPDT_IDLE;
[2]4592            }
[184]4593            break;
[2]4594        }
4595        /////////////////////////
[184]4596        case INIT_CMD_UPDT_INDEX:  // send word index for a multi-update (from WRITE FSM)
[2]4597        {
[184]4598            r_init_cmd_cpt    = 0;
4599            if ( p_vci_ini.cmdack )  r_init_cmd_fsm = INIT_CMD_UPDT_DATA;
4600            break;
[2]4601        }
4602        ////////////////////////
[184]4603        case INIT_CMD_UPDT_DATA:  // send the data for a multi-update (from WRITE FSM)
[2]4604        {
[184]4605            if ( p_vci_ini.cmdack )
4606            {
4607                if ( r_init_cmd_cpt.read() == (r_write_to_init_cmd_count.read()-1) )
4608                {
4609                    r_init_cmd_fsm = INIT_CMD_UPDT_NLINE;
4610                    write_to_init_cmd_fifo_get = true;
4611                }
4612                else
4613                {
4614                    r_init_cmd_cpt = r_init_cmd_cpt.read() + 1;
4615                }
[2]4616            }
[184]4617            break;
[2]4618        }
4619        /////////////////////////
[184]4620        case INIT_CMD_SC_BRDCAST:       // send a broadcast-inval (from SC FSM)
[2]4621        {
[184]4622            if( p_vci_ini.cmdack )
4623            {
4624                m_cpt_inval_brdcast++;
4625                r_sc_to_init_cmd_brdcast_req = false;
4626                r_init_cmd_fsm = INIT_CMD_SC_UPDT_IDLE;
4627            }
4628            break;
[2]4629        }
[184]4630        ////////////////////////////
4631        case INIT_CMD_SC_UPDT_NLINE:   // send nline for a multi-update (from SC FSM)
[2]4632        {
[184]4633            if ( m_sc_to_init_cmd_inst_fifo.rok() )
4634            {
4635                if ( p_vci_ini.cmdack )
4636                {
4637                    m_cpt_update_mult++;
4638                    r_init_cmd_fsm = INIT_CMD_SC_UPDT_INDEX;
4639                }
4640            }
4641            else
4642            {
4643                if( r_sc_to_init_cmd_multi_req.read() ) r_sc_to_init_cmd_multi_req = false;
4644                r_init_cmd_fsm = INIT_CMD_SC_UPDT_IDLE;
[2]4645            }
[184]4646            break;
[2]4647        }
[184]4648        ////////////////////////////
4649        case INIT_CMD_SC_UPDT_INDEX:  // send word index for a multi-update (from SC FSM)
[2]4650        {
[184]4651            if ( p_vci_ini.cmdack )  r_init_cmd_fsm = INIT_CMD_SC_UPDT_DATA;
4652            break;
[2]4653        }
[184]4654        ///////////////////////////
4655        case INIT_CMD_SC_UPDT_DATA:  // send first data for a multi-update (from SC FSM)
[2]4656        {
[184]4657            if ( p_vci_ini.cmdack )
4658            {
4659                if ( r_sc_to_init_cmd_is_long.read() )
4660                {
4661                    r_init_cmd_fsm = INIT_CMD_SC_UPDT_DATA_HIGH;
4662                }
4663                else
4664                {
4665                    sc_to_init_cmd_fifo_get = true;
4666                    r_init_cmd_fsm = INIT_CMD_SC_UPDT_NLINE;
4667                }
[2]4668            }
[184]4669            break;
[2]4670        }
4671        ////////////////////////
[184]4672        case INIT_CMD_SC_UPDT_DATA_HIGH:  // send second data for a multi-update (from SC FSM)
[2]4673        {
[184]4674            if ( p_vci_ini.cmdack )
4675            {
4676                sc_to_init_cmd_fifo_get = true;
4677                r_init_cmd_fsm = INIT_CMD_SC_UPDT_NLINE;
4678            }
4679            break;
[2]4680        }
4681    } // end switch r_init_cmd_fsm
4682
4683    /////////////////////////////////////////////////////////////////////
4684    //          TGT_RSP FSM
4685    /////////////////////////////////////////////////////////////////////
4686    // The TGT_RSP fsm sends the responses on the VCI target port
4687    // with a round robin priority between six requests :
4688    // - r_read_to_tgt_rsp_req
4689    // - r_write_to_tgt_rsp_req
[184]4690    // - r_sc_to_tgt_rsp_req
[2]4691    // - r_cleanup_to_tgt_rsp_req
[184]4692    // - r_xram_rsp_to_tgt_rsp_req
[2]4693    // - r_init_rsp_to_tgt_rsp_req
[184]4694    // The  ordering is :  read > write > sc > xram > init > cleanup
[2]4695    /////////////////////////////////////////////////////////////////////
4696
[184]4697    switch ( r_tgt_rsp_fsm.read() )
4698    {
4699        ///////////////////////
4700        case TGT_RSP_READ_IDLE:         // write requests have the highest priority
[2]4701        {
4702          if      ( r_write_to_tgt_rsp_req    ) r_tgt_rsp_fsm = TGT_RSP_WRITE;
[184]4703          else if ( r_sc_to_tgt_rsp_req     ) r_tgt_rsp_fsm = TGT_RSP_SC;
4704          else if ( r_xram_rsp_to_tgt_rsp_req )
4705          {
[2]4706            r_tgt_rsp_fsm = TGT_RSP_XRAM;
4707            r_tgt_rsp_cpt = r_xram_rsp_to_tgt_rsp_word.read();
4708          }
4709          else if ( r_init_rsp_to_tgt_rsp_req ) r_tgt_rsp_fsm = TGT_RSP_INIT;
4710          else if ( r_cleanup_to_tgt_rsp_req  ) r_tgt_rsp_fsm = TGT_RSP_CLEANUP;
[184]4711          else if ( r_read_to_tgt_rsp_req     )
4712          {
[2]4713            r_tgt_rsp_fsm = TGT_RSP_READ;
4714            r_tgt_rsp_cpt = r_read_to_tgt_rsp_word.read();
4715          }
4716          break;
4717        }
4718        ////////////////////////
[184]4719        case TGT_RSP_WRITE_IDLE:        // sc requests have the highest priority
[2]4720        {
[184]4721          if      ( r_sc_to_tgt_rsp_req     ) r_tgt_rsp_fsm = TGT_RSP_SC;
4722          else if ( r_xram_rsp_to_tgt_rsp_req )
4723          {
[2]4724            r_tgt_rsp_fsm = TGT_RSP_XRAM;
4725            r_tgt_rsp_cpt = r_xram_rsp_to_tgt_rsp_word.read();
4726          }
4727          else if ( r_init_rsp_to_tgt_rsp_req ) r_tgt_rsp_fsm = TGT_RSP_INIT;
4728          else if ( r_cleanup_to_tgt_rsp_req  ) r_tgt_rsp_fsm = TGT_RSP_CLEANUP;
[184]4729          else if ( r_read_to_tgt_rsp_req     )
4730          {
[2]4731            r_tgt_rsp_fsm = TGT_RSP_READ;
4732            r_tgt_rsp_cpt = r_read_to_tgt_rsp_word.read();
4733          }
4734
4735          else if ( r_write_to_tgt_rsp_req    ) r_tgt_rsp_fsm = TGT_RSP_WRITE;
4736          break;
4737        }
4738        ///////////////////////
[184]4739        case TGT_RSP_SC_IDLE:           // xram_rsp requests have the highest priority
[2]4740        {
[184]4741          if ( r_xram_rsp_to_tgt_rsp_req ) 
4742          {
[2]4743            r_tgt_rsp_fsm = TGT_RSP_XRAM;
4744            r_tgt_rsp_cpt = r_xram_rsp_to_tgt_rsp_word.read();
4745          }
4746          else if ( r_init_rsp_to_tgt_rsp_req ) r_tgt_rsp_fsm = TGT_RSP_INIT;
4747          else if ( r_cleanup_to_tgt_rsp_req  ) r_tgt_rsp_fsm = TGT_RSP_CLEANUP;
[184]4748          else if ( r_read_to_tgt_rsp_req     )
4749          {
[2]4750            r_tgt_rsp_fsm = TGT_RSP_READ;
4751            r_tgt_rsp_cpt = r_read_to_tgt_rsp_word.read();
4752          }
4753          else if ( r_write_to_tgt_rsp_req    ) r_tgt_rsp_fsm = TGT_RSP_WRITE;
[184]4754          else if ( r_sc_to_tgt_rsp_req     ) r_tgt_rsp_fsm = TGT_RSP_SC;
[2]4755          break;
4756        }
[184]4757        ///////////////////////
4758        case TGT_RSP_XRAM_IDLE:         // init requests have the highest priority
[2]4759        {
4760
4761          if      ( r_init_rsp_to_tgt_rsp_req ) r_tgt_rsp_fsm = TGT_RSP_INIT;
4762          else if ( r_cleanup_to_tgt_rsp_req  ) r_tgt_rsp_fsm = TGT_RSP_CLEANUP;
[184]4763          else if ( r_read_to_tgt_rsp_req     )
4764          {
[2]4765            r_tgt_rsp_fsm = TGT_RSP_READ;
4766            r_tgt_rsp_cpt = r_read_to_tgt_rsp_word.read();
4767          }
4768          else if ( r_write_to_tgt_rsp_req    ) r_tgt_rsp_fsm = TGT_RSP_WRITE;
[184]4769          else if ( r_sc_to_tgt_rsp_req     ) r_tgt_rsp_fsm = TGT_RSP_SC;
4770          else if ( r_xram_rsp_to_tgt_rsp_req ) 
4771          {
[2]4772            r_tgt_rsp_fsm = TGT_RSP_XRAM;
4773            r_tgt_rsp_cpt = r_xram_rsp_to_tgt_rsp_word.read();
4774          }
4775          break;
4776        }
4777        ///////////////////////
[184]4778        case TGT_RSP_INIT_IDLE:         // cleanup requests have the highest priority
[2]4779        {
4780          if      ( r_cleanup_to_tgt_rsp_req  ) r_tgt_rsp_fsm = TGT_RSP_CLEANUP;
[184]4781          else if ( r_read_to_tgt_rsp_req     )
4782          {
[2]4783            r_tgt_rsp_fsm = TGT_RSP_READ;
4784            r_tgt_rsp_cpt = r_read_to_tgt_rsp_word.read();
4785          }
4786          else if ( r_write_to_tgt_rsp_req    ) r_tgt_rsp_fsm = TGT_RSP_WRITE;
[184]4787          else if ( r_sc_to_tgt_rsp_req     ) r_tgt_rsp_fsm = TGT_RSP_SC;
4788          else if ( r_xram_rsp_to_tgt_rsp_req )
4789          {
[2]4790            r_tgt_rsp_fsm = TGT_RSP_XRAM;
4791            r_tgt_rsp_cpt = r_xram_rsp_to_tgt_rsp_word.read();
4792          }
4793          else if ( r_init_rsp_to_tgt_rsp_req ) r_tgt_rsp_fsm = TGT_RSP_INIT;
4794          break;
4795        }
4796        ///////////////////////
[184]4797        case TGT_RSP_CLEANUP_IDLE:              // read requests have the highest priority
[2]4798        {
[184]4799          if      ( r_read_to_tgt_rsp_req     )
4800          {
[2]4801            r_tgt_rsp_fsm = TGT_RSP_READ;
4802            r_tgt_rsp_cpt = r_read_to_tgt_rsp_word.read();
4803          }
4804          else if ( r_write_to_tgt_rsp_req    ) r_tgt_rsp_fsm = TGT_RSP_WRITE;
[184]4805          else if ( r_sc_to_tgt_rsp_req     ) r_tgt_rsp_fsm = TGT_RSP_SC;
4806          else if ( r_xram_rsp_to_tgt_rsp_req )
4807          {
[2]4808            r_tgt_rsp_fsm = TGT_RSP_XRAM;
4809            r_tgt_rsp_cpt = r_xram_rsp_to_tgt_rsp_word.read();
4810          }
4811          else if ( r_init_rsp_to_tgt_rsp_req ) r_tgt_rsp_fsm = TGT_RSP_INIT;
4812          else if ( r_cleanup_to_tgt_rsp_req  ) r_tgt_rsp_fsm = TGT_RSP_CLEANUP;
4813          break;
4814        }
[184]4815        //////////////////
4816        case TGT_RSP_READ:              // send the response to a read
[2]4817        {
[184]4818            if ( p_vci_tgt.rspack )
4819            {
[175]4820
[184]4821#if DEBUG_MEMC_TGT_RSP
4822if( m_debug_tgt_rsp_fsm )
4823{
4824    std::cout << "  <MEMC.TGT_RSP_READ> Read response"
4825              << " / rsrcid = " << std::hex << r_read_to_tgt_rsp_srcid.read()
4826              << " / rtrdid = " << r_read_to_tgt_rsp_trdid.read()
4827              << " / rdata = " << r_read_to_tgt_rsp_data[r_tgt_rsp_cpt.read()].read()
4828              << " / cpt = " << std::dec << r_tgt_rsp_cpt.read() << std::endl;
4829}
4830#endif
4831                if ( r_tgt_rsp_cpt.read() == (r_read_to_tgt_rsp_word.read()+r_read_to_tgt_rsp_length-1) )
4832                {
4833                    r_tgt_rsp_fsm = TGT_RSP_READ_IDLE;
4834                    r_read_to_tgt_rsp_req = false;
4835                }
4836                else
4837                {
4838                    r_tgt_rsp_cpt = r_tgt_rsp_cpt.read() + 1;
4839                }
[2]4840            }
[184]4841            break;
[2]4842        }
4843        ///////////////////
[184]4844        case TGT_RSP_WRITE:             // send the write acknowledge
[2]4845        {
[184]4846            if ( p_vci_tgt.rspack )
4847            {
4848
4849#if DEBUG_MEMC_TGT_RSP
4850if( m_debug_tgt_rsp_fsm )
4851{
4852    std::cout << "  <MEMC.TGT_RSP_WRITE> Write response"
4853              << " / rsrcid = " << r_write_to_tgt_rsp_srcid.read()
4854              << " / rtrdid = " << r_write_to_tgt_rsp_trdid.read() << std::endl;
4855}
4856#endif
4857                r_tgt_rsp_fsm = TGT_RSP_WRITE_IDLE;
4858                r_write_to_tgt_rsp_req = false;
4859            }
4860            break;
[2]4861        }
4862        ///////////////////
[184]4863        case TGT_RSP_CLEANUP:           // pas clair pour moi (AG)   
[2]4864        {
[184]4865            if ( p_vci_tgt.rspack )
4866            {
4867
4868#if DEBUG_MEMC_TGT_RSP
4869if( m_debug_tgt_rsp_fsm )
4870{
4871    std::cout << "  <MEMC.TGT_RSP_CLEANUP> Cleanup response"
4872              << " / rsrcid = " << r_cleanup_to_tgt_rsp_srcid.read()
4873              << " / rtrdid = " << r_cleanup_to_tgt_rsp_trdid.read() << std::endl;
4874}
4875#endif
4876                r_tgt_rsp_fsm = TGT_RSP_CLEANUP_IDLE;
4877                r_cleanup_to_tgt_rsp_req = false;
4878            }
4879            break;
[2]4880        }
4881        //////////////////
[184]4882        case TGT_RSP_SC:                // send one atomic word response
[2]4883        {
[184]4884            if ( p_vci_tgt.rspack )
4885            {
4886
4887#if DEBUG_MEMC_TGT_RSP
4888if( m_debug_tgt_rsp_fsm )
4889{
4890    std::cout << "  <MEMC.TGT_RSP_SC> SC response"
4891              << " / rsrcid = " << r_sc_to_tgt_rsp_srcid.read()
4892              << " / rtrdid = " << r_sc_to_tgt_rsp_trdid.read() << std::endl;
4893}
4894#endif
4895                r_tgt_rsp_fsm = TGT_RSP_SC_IDLE;
4896                r_sc_to_tgt_rsp_req = false;
4897            }
4898            break;
[2]4899        }
4900
4901        ///////////////////////
[184]4902        case TGT_RSP_XRAM:              // send the response after XRAM access
[2]4903        {
[184]4904            if ( p_vci_tgt.rspack )
4905            {
4906
4907#if DEBUG_MEMC_TGT_RSP
4908if( m_debug_tgt_rsp_fsm )
4909{
4910    std::cout << "  <MEMC.TGT_RSP_XRAM> Response following XRAM access"
4911              << " / rsrcid = " << r_xram_rsp_to_tgt_rsp_srcid.read()
4912              << " / rtrdid = " << r_xram_rsp_to_tgt_rsp_trdid.read()
4913              << " / rdata = " << r_xram_rsp_to_tgt_rsp_data[r_tgt_rsp_cpt.read()].read()
4914              << " / cpt = " << r_tgt_rsp_cpt.read() << std::endl;
4915}
4916#endif
4917                if ( (r_tgt_rsp_cpt.read() ==
4918                     (r_xram_rsp_to_tgt_rsp_word.read()+r_xram_rsp_to_tgt_rsp_length.read()-1))
4919                   || r_xram_rsp_to_tgt_rsp_rerror.read() )
4920                {
4921                    r_tgt_rsp_fsm = TGT_RSP_XRAM_IDLE;
4922                    r_xram_rsp_to_tgt_rsp_req = false;
4923                }
4924                else
4925                {
4926                    r_tgt_rsp_cpt = r_tgt_rsp_cpt.read() + 1;
4927                }
[2]4928            }
[184]4929            break;
[2]4930        }
[184]4931        //////////////////
4932        case TGT_RSP_INIT:              // send the write response after coherence transaction
[2]4933        {
[184]4934            if ( p_vci_tgt.rspack )
4935            {
4936
4937#if DEBUG_MEMC_TGT_RSP
4938if( m_debug_tgt_rsp_fsm )
4939{
4940    std::cout << "  <MEMC.TGT_RSP_INIT> Write response after coherence transaction"
4941              << " / rsrcid = " << r_init_rsp_to_tgt_rsp_srcid.read()
4942              << " / rtrdid = " << r_init_rsp_to_tgt_rsp_trdid.read() << std::endl;
4943}
4944#endif
4945                r_tgt_rsp_fsm = TGT_RSP_INIT_IDLE;
4946                r_init_rsp_to_tgt_rsp_req = false;
4947            }
4948            break;
[2]4949        }
4950    } // end switch tgt_rsp_fsm
[184]4951
[2]4952    ////////////////////////////////////////////////////////////////////////////////////
[184]4953    //          ALLOC_UPT FSM
[2]4954    ////////////////////////////////////////////////////////////////////////////////////
4955    // The ALLOC_UPT FSM allocates the access to the Update/Inval Table (UPT).
4956    // with a round robin priority between three FSMs : INIT_RSP > WRITE > XRAM_RSP > CLEANUP
4957    // - The WRITE FSM initiates update transactions and sets  new entry in UPT.
4958    // - The XRAM_RSP FSM initiates inval transactions and sets  new entry in UPT.
4959    // - The INIT_RSP FSM complete those trasactions and erase the UPT entry.
4960    // - The CLEANUP  FSM decrement an entry in UPT.
4961    // The resource is always allocated.
4962    /////////////////////////////////////////////////////////////////////////////////////
4963
[184]4964    switch ( r_alloc_upt_fsm.read() )
4965    {
[2]4966
4967      ////////////////////////
4968      case ALLOC_UPT_INIT_RSP:
4969        if ( (r_init_rsp_fsm.read() != INIT_RSP_UPT_LOCK) &&
4970             (r_init_rsp_fsm.read() != INIT_RSP_UPT_CLEAR) )
4971        {
4972          if      ((r_write_fsm.read() == WRITE_UPT_LOCK) ||
[200]4973                   (r_write_fsm.read() == WRITE_BC_UPT_LOCK))        r_alloc_upt_fsm = ALLOC_UPT_WRITE;
[2]4974          else if (r_xram_rsp_fsm.read() == XRAM_RSP_INVAL_LOCK)    r_alloc_upt_fsm = ALLOC_UPT_XRAM_RSP;
4975          else if (r_cleanup_fsm.read() == CLEANUP_UPT_LOCK)        r_alloc_upt_fsm = ALLOC_UPT_CLEANUP;
[184]4976          else if ((r_sc_fsm.read() == SC_UPT_LOCK) ||
[200]4977                   (r_sc_fsm.read() == SC_BC_UPT_LOCK))            r_alloc_upt_fsm = ALLOC_UPT_SC;
[2]4978        }
4979        break;
4980
4981        /////////////////////
4982      case ALLOC_UPT_WRITE:
4983        if ( (r_write_fsm.read() != WRITE_UPT_LOCK) &&
[200]4984             (r_write_fsm.read() != WRITE_BC_UPT_LOCK))
[2]4985        {
4986          if      (r_xram_rsp_fsm.read() == XRAM_RSP_INVAL_LOCK)    r_alloc_upt_fsm = ALLOC_UPT_XRAM_RSP;
4987          else if (r_cleanup_fsm.read() == CLEANUP_UPT_LOCK)        r_alloc_upt_fsm = ALLOC_UPT_CLEANUP;
[184]4988          else if ((r_sc_fsm.read() == SC_UPT_LOCK) ||
[200]4989                   (r_sc_fsm.read() == SC_BC_UPT_LOCK))            r_alloc_upt_fsm = ALLOC_UPT_SC;
[2]4990          else if (r_init_rsp_fsm.read() == INIT_RSP_UPT_LOCK)      r_alloc_upt_fsm = ALLOC_UPT_INIT_RSP;
4991        }
4992        break;
4993
4994        ////////////////////////
4995      case ALLOC_UPT_XRAM_RSP:
4996        if (r_xram_rsp_fsm.read() != XRAM_RSP_INVAL_LOCK)
4997        {
4998          if       (r_cleanup_fsm.read() == CLEANUP_UPT_LOCK)       r_alloc_upt_fsm = ALLOC_UPT_CLEANUP;
[184]4999          else if ((r_sc_fsm.read() == SC_UPT_LOCK) ||
[200]5000                   (r_sc_fsm.read() == SC_BC_UPT_LOCK))            r_alloc_upt_fsm = ALLOC_UPT_SC;
[2]5001          else if  (r_init_rsp_fsm.read() == INIT_RSP_UPT_LOCK)     r_alloc_upt_fsm = ALLOC_UPT_INIT_RSP;
5002          else if ((r_write_fsm.read() == WRITE_UPT_LOCK)   ||
[200]5003                   (r_write_fsm.read() == WRITE_BC_UPT_LOCK))        r_alloc_upt_fsm = ALLOC_UPT_WRITE;
[2]5004        }
5005        break;
5006
5007        //////////////////////////
5008      case ALLOC_UPT_CLEANUP:
5009        if(r_cleanup_fsm.read() != CLEANUP_UPT_LOCK )
5010        {
[184]5011          if      ((r_sc_fsm.read() == SC_UPT_LOCK) ||
[200]5012                   (r_sc_fsm.read() == SC_BC_UPT_LOCK))            r_alloc_upt_fsm = ALLOC_UPT_SC;
[2]5013          else if  (r_init_rsp_fsm.read() == INIT_RSP_UPT_LOCK)     r_alloc_upt_fsm = ALLOC_UPT_INIT_RSP;
5014          else if ((r_write_fsm.read() == WRITE_UPT_LOCK) ||
[200]5015                   (r_write_fsm.read() == WRITE_BC_UPT_LOCK))        r_alloc_upt_fsm = ALLOC_UPT_WRITE;
[2]5016          else if (r_xram_rsp_fsm.read() == XRAM_RSP_INVAL_LOCK)    r_alloc_upt_fsm = ALLOC_UPT_XRAM_RSP;
5017        }
5018        break;
5019       
5020        //////////////////////////
[184]5021      case ALLOC_UPT_SC:
5022        if( (r_sc_fsm.read() != SC_UPT_LOCK) &&
[200]5023            (r_sc_fsm.read() != SC_BC_UPT_LOCK))
[2]5024        {
5025          if      (r_init_rsp_fsm.read() == INIT_RSP_UPT_LOCK)      r_alloc_upt_fsm = ALLOC_UPT_INIT_RSP;
5026          else if ((r_write_fsm.read() == WRITE_UPT_LOCK) ||
[200]5027                   (r_write_fsm.read() == WRITE_BC_UPT_LOCK))        r_alloc_upt_fsm = ALLOC_UPT_WRITE;
[2]5028          else if (r_xram_rsp_fsm.read() == XRAM_RSP_INVAL_LOCK)    r_alloc_upt_fsm = ALLOC_UPT_XRAM_RSP;
5029          else if (r_cleanup_fsm.read() == CLEANUP_UPT_LOCK)        r_alloc_upt_fsm = ALLOC_UPT_CLEANUP;
5030        }
5031        break;
5032
5033    } // end switch r_alloc_upt_fsm
5034
5035    ////////////////////////////////////////////////////////////////////////////////////
5036    //          ALLOC_DIR FSM
5037    ////////////////////////////////////////////////////////////////////////////////////
5038    // The ALLOC_DIR FSM allocates the access to the directory and
5039    // the data cache with a round robin priority between 5 user FSMs :
[184]5040    // The cyclic ordering is READ > WRITE > SC > CLEANUP > XRAM_RSP
[2]5041    // The ressource is always allocated.
5042    /////////////////////////////////////////////////////////////////////////////////////
5043
[184]5044    switch ( r_alloc_dir_fsm.read() )
5045    {
[2]5046
5047      ////////////////////
5048      case ALLOC_DIR_READ:
5049        if ( ( (r_read_fsm.read() != READ_DIR_LOCK) &&
5050              (r_read_fsm.read() != READ_TRT_LOCK)  &&
5051              (r_read_fsm.read() != READ_HEAP_LOCK))
5052            ||
5053            ( (r_read_fsm.read()        == READ_HEAP_LOCK) &&
5054              (r_alloc_heap_fsm.read()  == ALLOC_HEAP_READ) )
5055            ||
5056            ( (r_read_fsm.read()      == READ_TRT_LOCK)  &&
5057              (r_alloc_trt_fsm.read() == ALLOC_TRT_READ)    )  )
5058        {
5059          if        (r_write_fsm.read() == WRITE_DIR_LOCK)          r_alloc_dir_fsm = ALLOC_DIR_WRITE;
[184]5060          else if   (r_sc_fsm.read() == SC_DIR_LOCK)              r_alloc_dir_fsm = ALLOC_DIR_SC;
[2]5061          else if   (r_cleanup_fsm.read() == CLEANUP_DIR_LOCK)      r_alloc_dir_fsm = ALLOC_DIR_CLEANUP;
5062          else if   (r_xram_rsp_fsm.read() == XRAM_RSP_DIR_LOCK)    r_alloc_dir_fsm = ALLOC_DIR_XRAM_RSP;
5063        }
5064        break;
5065
5066        /////////////////////
5067      case ALLOC_DIR_WRITE:
[200]5068        if ( ((r_write_fsm.read() != WRITE_DIR_LOCK) &&
5069              (r_write_fsm.read() != WRITE_MISS_TRT_LOCK) &&
5070              (r_write_fsm.read() != WRITE_DIR_READ) &&
[2]5071              (r_write_fsm.read() != WRITE_DIR_HIT) &&
[200]5072              (r_write_fsm.read() != WRITE_BC_TRT_LOCK) &&
5073              (r_write_fsm.read() != WRITE_BC_UPT_LOCK) &&
[2]5074              (r_write_fsm.read() != WRITE_UPT_LOCK) &&
[200]5075              (r_write_fsm.read() != WRITE_UPT_HEAP_LOCK))
[2]5076            ||
[200]5077            ( (r_write_fsm.read()       == WRITE_UPT_HEAP_LOCK) &&
[2]5078              (r_alloc_heap_fsm.read()  == ALLOC_HEAP_WRITE) )
5079            ||
[200]5080            ( (r_write_fsm.read()     == WRITE_MISS_TRT_LOCK) &&
[2]5081              (r_alloc_trt_fsm.read() == ALLOC_TRT_WRITE)   )   )
5082        {
[184]5083          if        (r_sc_fsm.read() == SC_DIR_LOCK)              r_alloc_dir_fsm = ALLOC_DIR_SC;
[2]5084          else if   (r_cleanup_fsm.read() == CLEANUP_DIR_LOCK)      r_alloc_dir_fsm = ALLOC_DIR_CLEANUP;
5085          else if   (r_xram_rsp_fsm.read() == XRAM_RSP_DIR_LOCK)    r_alloc_dir_fsm = ALLOC_DIR_XRAM_RSP;
5086          else if   (r_read_fsm.read() == READ_DIR_LOCK)                r_alloc_dir_fsm = ALLOC_DIR_READ;
5087        }
5088        break;
5089
5090        ////////////////////
[184]5091        case ALLOC_DIR_SC:
5092        if ( ((r_sc_fsm.read() != SC_DIR_LOCK)       &&
5093              (r_sc_fsm.read() != SC_DIR_HIT_READ )  &&
5094              (r_sc_fsm.read() != SC_DIR_HIT_WRITE ) &&
[200]5095//              (r_sc_fsm.read() != SC_MISS_TRT_LOCK )    &&
5096              (r_sc_fsm.read() != SC_BC_TRT_LOCK)       &&
5097              (r_sc_fsm.read() != SC_BC_UPT_LOCK)     &&
[184]5098              (r_sc_fsm.read() != SC_UPT_LOCK)       &&
[200]5099              (r_sc_fsm.read() != SC_UPT_HEAP_LOCK))
[2]5100            ||
[200]5101            ( (r_sc_fsm.read()       == SC_UPT_HEAP_LOCK) &&
[184]5102              (r_alloc_heap_fsm.read() == ALLOC_HEAP_SC) )
[2]5103            ||
[200]5104            ( (r_sc_fsm.read()      == SC_MISS_TRT_LOCK ) &&
[184]5105              (r_alloc_trt_fsm.read() == ALLOC_TRT_SC)    ) )
[2]5106        {
5107          if      (r_cleanup_fsm.read() == CLEANUP_DIR_LOCK)    r_alloc_dir_fsm = ALLOC_DIR_CLEANUP;
5108          else if (r_xram_rsp_fsm.read() == XRAM_RSP_DIR_LOCK)  r_alloc_dir_fsm = ALLOC_DIR_XRAM_RSP;
5109          else if (r_read_fsm.read() == READ_DIR_LOCK)          r_alloc_dir_fsm = ALLOC_DIR_READ;
5110          else if (r_write_fsm.read() == WRITE_DIR_LOCK)        r_alloc_dir_fsm = ALLOC_DIR_WRITE;
5111        }
5112        break;
5113
5114        ///////////////////////
[184]5115        case ALLOC_DIR_CLEANUP:
[2]5116        if ( (r_cleanup_fsm.read() != CLEANUP_DIR_LOCK) &&
5117            (r_cleanup_fsm.read() != CLEANUP_HEAP_LOCK) )
5118        {
5119          if        (r_xram_rsp_fsm.read() == XRAM_RSP_DIR_LOCK)    r_alloc_dir_fsm = ALLOC_DIR_XRAM_RSP;
5120          else if   (r_read_fsm.read() == READ_DIR_LOCK)            r_alloc_dir_fsm = ALLOC_DIR_READ;
5121          else if   (r_write_fsm.read() == WRITE_DIR_LOCK)          r_alloc_dir_fsm = ALLOC_DIR_WRITE;
[184]5122          else if   (r_sc_fsm.read() == SC_DIR_LOCK)              r_alloc_dir_fsm = ALLOC_DIR_SC;
[2]5123        }
5124        break;
5125        ////////////////////////
[184]5126        case ALLOC_DIR_XRAM_RSP:
[2]5127        if ( (r_xram_rsp_fsm.read() != XRAM_RSP_DIR_LOCK)  &&
5128            (r_xram_rsp_fsm.read() != XRAM_RSP_TRT_COPY)   &&
5129            (r_xram_rsp_fsm.read() != XRAM_RSP_INVAL_LOCK))
5130        {
5131          if      (r_read_fsm.read() == READ_DIR_LOCK)          r_alloc_dir_fsm = ALLOC_DIR_READ;
5132          else if (r_write_fsm.read() == WRITE_DIR_LOCK)        r_alloc_dir_fsm = ALLOC_DIR_WRITE;
[184]5133          else if (r_sc_fsm.read() == SC_DIR_LOCK)            r_alloc_dir_fsm = ALLOC_DIR_SC;
[2]5134          else if (r_cleanup_fsm.read() == CLEANUP_DIR_LOCK)    r_alloc_dir_fsm = ALLOC_DIR_CLEANUP;
5135        }
5136        break;
5137
5138    } // end switch alloc_dir_fsm
5139
5140    ////////////////////////////////////////////////////////////////////////////////////
5141    //          ALLOC_TRT FSM
5142    ////////////////////////////////////////////////////////////////////////////////////
5143    // The ALLOC_TRT fsm allocates the access to the Transaction Table (write buffer)
5144    // with a round robin priority between 4 user FSMs :
[184]5145    // The cyclic priority is READ > WRITE > SC > XRAM_RSP
[2]5146    // The ressource is always allocated.
5147    ///////////////////////////////////////////////////////////////////////////////////
5148
[184]5149    switch (r_alloc_trt_fsm)
5150    {
[2]5151
5152      ////////////////////
5153      case ALLOC_TRT_READ:
5154        if ( r_read_fsm.read() != READ_TRT_LOCK )
5155        {
[200]5156          if      ((r_write_fsm.read() == WRITE_MISS_TRT_LOCK)   ||
5157                   (r_write_fsm.read() == WRITE_BC_TRT_LOCK))    r_alloc_trt_fsm = ALLOC_TRT_WRITE;
5158          else if ((r_sc_fsm.read() == SC_MISS_TRT_LOCK) ||
5159                   (r_sc_fsm.read() == SC_BC_TRT_LOCK))              r_alloc_trt_fsm = ALLOC_TRT_SC;
[2]5160          else if (r_xram_rsp_fsm.read() == XRAM_RSP_TRT_COPY)      r_alloc_trt_fsm = ALLOC_TRT_XRAM_RSP;
5161          else if ( (r_ixr_rsp_fsm.read() == IXR_RSP_TRT_ERASE) ||
5162                    (r_ixr_rsp_fsm.read() == IXR_RSP_TRT_READ) )    r_alloc_trt_fsm = ALLOC_TRT_IXR_RSP;
5163        }
5164        break;
5165        /////////////////////
5166      case ALLOC_TRT_WRITE:
[200]5167        if ( (r_write_fsm.read() != WRITE_MISS_TRT_LOCK) &&
5168             (r_write_fsm.read() != WRITE_BC_TRT_LOCK) &&
5169             (r_write_fsm.read() != WRITE_BC_UPT_LOCK))
[2]5170        {
[200]5171          if      ((r_sc_fsm.read() == SC_MISS_TRT_LOCK) ||
5172                   (r_sc_fsm.read() == SC_BC_TRT_LOCK))              r_alloc_trt_fsm = ALLOC_TRT_SC;
[2]5173          else if (r_xram_rsp_fsm.read() == XRAM_RSP_TRT_COPY)      r_alloc_trt_fsm = ALLOC_TRT_XRAM_RSP;
5174          else if ( (r_ixr_rsp_fsm.read() == IXR_RSP_TRT_ERASE) ||
5175                    (r_ixr_rsp_fsm.read() == IXR_RSP_TRT_READ))     r_alloc_trt_fsm = ALLOC_TRT_IXR_RSP;
5176          else if (r_read_fsm.read() == READ_TRT_LOCK)              r_alloc_trt_fsm = ALLOC_TRT_READ;
5177        }
5178        break;
5179        ////////////////////
[184]5180      case ALLOC_TRT_SC:
[200]5181        if ( (r_sc_fsm.read() != SC_MISS_TRT_LOCK) &&
5182             (r_sc_fsm.read() != SC_BC_TRT_LOCK) &&
5183             (r_sc_fsm.read() != SC_BC_UPT_LOCK))
[2]5184        {
5185          if      (r_xram_rsp_fsm.read() == XRAM_RSP_TRT_COPY)      r_alloc_trt_fsm = ALLOC_TRT_XRAM_RSP;
5186          else if ( (r_ixr_rsp_fsm.read() == IXR_RSP_TRT_ERASE) ||
5187                    (r_ixr_rsp_fsm.read() == IXR_RSP_TRT_READ))     r_alloc_trt_fsm = ALLOC_TRT_IXR_RSP;
5188          else if (r_read_fsm.read() == READ_TRT_LOCK)              r_alloc_trt_fsm = ALLOC_TRT_READ;
[200]5189          else if ((r_write_fsm.read() == WRITE_MISS_TRT_LOCK)     ||
5190                   (r_write_fsm.read() == WRITE_BC_TRT_LOCK))    r_alloc_trt_fsm = ALLOC_TRT_WRITE;
[2]5191        }
5192        break;
5193        ////////////////////////
5194      case ALLOC_TRT_XRAM_RSP:
5195        if ( (r_xram_rsp_fsm.read() != XRAM_RSP_TRT_COPY)  &&
5196            (r_xram_rsp_fsm.read() != XRAM_RSP_DIR_UPDT)   &&
5197            (r_xram_rsp_fsm.read() != XRAM_RSP_INVAL_LOCK)) {
5198          if      ( (r_ixr_rsp_fsm.read() == IXR_RSP_TRT_ERASE) ||
5199                    (r_ixr_rsp_fsm.read() == IXR_RSP_TRT_READ))     r_alloc_trt_fsm = ALLOC_TRT_IXR_RSP;
5200          else if (r_read_fsm.read() == READ_TRT_LOCK)              r_alloc_trt_fsm = ALLOC_TRT_READ;
[200]5201          else if ((r_write_fsm.read() == WRITE_MISS_TRT_LOCK)    ||
5202                   (r_write_fsm.read() == WRITE_BC_TRT_LOCK))    r_alloc_trt_fsm = ALLOC_TRT_WRITE;
5203          else if ((r_sc_fsm.read() == SC_MISS_TRT_LOCK) ||
5204                   (r_sc_fsm.read() == SC_BC_TRT_LOCK))              r_alloc_trt_fsm = ALLOC_TRT_SC;
[2]5205        }
5206        break;
5207        ////////////////////////
5208      case ALLOC_TRT_IXR_RSP:
5209        if ( (r_ixr_rsp_fsm.read() != IXR_RSP_TRT_ERASE) &&
5210            (r_ixr_rsp_fsm.read() != IXR_RSP_TRT_READ) ) {
5211          if      (r_read_fsm.read() == READ_TRT_LOCK)              r_alloc_trt_fsm = ALLOC_TRT_READ;
[200]5212          else if ((r_write_fsm.read() == WRITE_MISS_TRT_LOCK)   ||
5213                   (r_write_fsm.read() == WRITE_BC_TRT_LOCK))    r_alloc_trt_fsm = ALLOC_TRT_WRITE;
5214          else if ((r_sc_fsm.read() == SC_MISS_TRT_LOCK) ||
5215                   (r_sc_fsm.read() == SC_BC_TRT_LOCK))              r_alloc_trt_fsm = ALLOC_TRT_SC;
[2]5216          else if (r_xram_rsp_fsm.read() == XRAM_RSP_TRT_COPY)      r_alloc_trt_fsm = ALLOC_TRT_XRAM_RSP;
5217        }
5218        break;
5219
5220    } // end switch alloc_trt_fsm
5221
5222    ////////////////////////////////////////////////////////////////////////////////////
5223    //          ALLOC_HEAP FSM
5224    ////////////////////////////////////////////////////////////////////////////////////
5225    // The ALLOC_HEAP FSM allocates the access to the heap
5226    // with a round robin priority between 5 user FSMs :
[184]5227    // The cyclic ordering is READ > WRITE > SC > CLEANUP > XRAM_RSP
[2]5228    // The ressource is always allocated.
5229    /////////////////////////////////////////////////////////////////////////////////////
5230
[184]5231    switch ( r_alloc_heap_fsm.read() )
5232    {
[200]5233        ////////////////////
5234        case ALLOC_HEAP_READ:
[2]5235        if (  (r_read_fsm.read() != READ_HEAP_LOCK) &&
5236              (r_read_fsm.read() != READ_HEAP_ERASE)     )
5237        {
[200]5238          if      (r_write_fsm.read() == WRITE_UPT_HEAP_LOCK)    r_alloc_heap_fsm = ALLOC_HEAP_WRITE;
5239          else if (r_sc_fsm.read() == SC_UPT_HEAP_LOCK)              r_alloc_heap_fsm = ALLOC_HEAP_SC;
5240          else if (r_cleanup_fsm.read() == CLEANUP_HEAP_LOCK)    r_alloc_heap_fsm = ALLOC_HEAP_CLEANUP;
5241          else if (r_xram_rsp_fsm.read() == XRAM_RSP_HEAP_ERASE) r_alloc_heap_fsm = ALLOC_HEAP_XRAM_RSP;
[2]5242        }
5243        break;
5244
5245        /////////////////////
[200]5246        case ALLOC_HEAP_WRITE:
5247        if (  (r_write_fsm.read() != WRITE_UPT_HEAP_LOCK)   &&
[2]5248              (r_write_fsm.read() != WRITE_UPT_REQ)     &&
[200]5249              (r_write_fsm.read() != WRITE_UPT_NEXT)  )
[2]5250        {
[200]5251          if      (r_sc_fsm.read() == SC_UPT_HEAP_LOCK)          r_alloc_heap_fsm = ALLOC_HEAP_SC;
5252          else if (r_cleanup_fsm.read() == CLEANUP_HEAP_LOCK)    r_alloc_heap_fsm = ALLOC_HEAP_CLEANUP;
5253          else if (r_xram_rsp_fsm.read() == XRAM_RSP_HEAP_ERASE) r_alloc_heap_fsm = ALLOC_HEAP_XRAM_RSP;
5254          else if (r_read_fsm.read() == READ_HEAP_LOCK)              r_alloc_heap_fsm = ALLOC_HEAP_READ;
[2]5255        }
5256        break;
5257
5258        ////////////////////
[200]5259        case ALLOC_HEAP_SC:
5260        if (  (r_sc_fsm.read() != SC_UPT_HEAP_LOCK)  &&
[184]5261              (r_sc_fsm.read() != SC_UPT_REQ )    &&
5262              (r_sc_fsm.read() != SC_UPT_NEXT)  )
[2]5263        {
[200]5264          if      (r_cleanup_fsm.read() == CLEANUP_HEAP_LOCK)    r_alloc_heap_fsm = ALLOC_HEAP_CLEANUP;
5265          else if (r_xram_rsp_fsm.read() == XRAM_RSP_HEAP_ERASE) r_alloc_heap_fsm = ALLOC_HEAP_XRAM_RSP;
5266          else if (r_read_fsm.read() == READ_HEAP_LOCK)          r_alloc_heap_fsm = ALLOC_HEAP_READ;
5267          else if (r_write_fsm.read() == WRITE_UPT_HEAP_LOCK)    r_alloc_heap_fsm = ALLOC_HEAP_WRITE;
[2]5268        }
5269        break;
5270
5271        ///////////////////////
[200]5272        case ALLOC_HEAP_CLEANUP:
[2]5273        if ( (r_cleanup_fsm.read() != CLEANUP_HEAP_LOCK) &&
5274            (r_cleanup_fsm.read() != CLEANUP_HEAP_SEARCH)&&
5275            (r_cleanup_fsm.read() != CLEANUP_HEAP_CLEAN)    )
5276        {
[200]5277          if      (r_xram_rsp_fsm.read() == XRAM_RSP_HEAP_ERASE) r_alloc_heap_fsm = ALLOC_HEAP_XRAM_RSP;
5278          else if (r_read_fsm.read() == READ_HEAP_LOCK)          r_alloc_heap_fsm = ALLOC_HEAP_READ;
5279          else if (r_write_fsm.read() == WRITE_UPT_HEAP_LOCK)    r_alloc_heap_fsm = ALLOC_HEAP_WRITE;
5280          else if (r_sc_fsm.read() == SC_UPT_HEAP_LOCK)          r_alloc_heap_fsm = ALLOC_HEAP_SC;
[2]5281        }
5282        break;
5283        ////////////////////////
[200]5284        case ALLOC_HEAP_XRAM_RSP:
[2]5285        if ( r_xram_rsp_fsm.read() != XRAM_RSP_HEAP_ERASE )
5286        {
[200]5287          if        (r_read_fsm.read() == READ_HEAP_LOCK)           r_alloc_heap_fsm = ALLOC_HEAP_READ;
5288          else if   (r_write_fsm.read() == WRITE_UPT_HEAP_LOCK) r_alloc_heap_fsm = ALLOC_HEAP_WRITE;
5289          else if   (r_sc_fsm.read() == SC_UPT_HEAP_LOCK)       r_alloc_heap_fsm = ALLOC_HEAP_SC;
5290          else if   (r_cleanup_fsm.read() == CLEANUP_HEAP_LOCK) r_alloc_heap_fsm = ALLOC_HEAP_CLEANUP;
[2]5291        }
5292        break;
5293
5294    } // end switch alloc_heap_fsm
5295
5296
5297    ////////////////////////////////////////////////////////////////////////////////////
5298    //          TGT_CMD to READ FIFO
5299    ////////////////////////////////////////////////////////////////////////////////////
5300
5301    if ( cmd_read_fifo_put ) {
5302      if ( cmd_read_fifo_get ) {
5303        m_cmd_read_addr_fifo.put_and_get((addr_t)(p_vci_tgt.address.read()));
5304        m_cmd_read_length_fifo.put_and_get(p_vci_tgt.plen.read()>>2);
5305        m_cmd_read_srcid_fifo.put_and_get(p_vci_tgt.srcid.read());
5306        m_cmd_read_trdid_fifo.put_and_get(p_vci_tgt.trdid.read());
5307        m_cmd_read_pktid_fifo.put_and_get(p_vci_tgt.pktid.read());
5308      } else {
5309        m_cmd_read_addr_fifo.simple_put((addr_t)(p_vci_tgt.address.read()));
5310        m_cmd_read_length_fifo.simple_put(p_vci_tgt.plen.read()>>2);
5311        m_cmd_read_srcid_fifo.simple_put(p_vci_tgt.srcid.read());
5312        m_cmd_read_trdid_fifo.simple_put(p_vci_tgt.trdid.read());
5313        m_cmd_read_pktid_fifo.simple_put(p_vci_tgt.pktid.read());
5314      }
5315    } else {
5316      if ( cmd_read_fifo_get ) {
5317        m_cmd_read_addr_fifo.simple_get();
5318        m_cmd_read_length_fifo.simple_get();
5319        m_cmd_read_srcid_fifo.simple_get();
5320        m_cmd_read_trdid_fifo.simple_get();
5321        m_cmd_read_pktid_fifo.simple_get();
5322      }
5323    }
5324    /////////////////////////////////////////////////////////////////////
5325    //          TGT_CMD to WRITE FIFO
5326    /////////////////////////////////////////////////////////////////////
5327
5328    if ( cmd_write_fifo_put ) {
5329      if ( cmd_write_fifo_get ) {
5330        m_cmd_write_addr_fifo.put_and_get((addr_t)(p_vci_tgt.address.read()));
5331        m_cmd_write_eop_fifo.put_and_get(p_vci_tgt.eop.read());
5332        m_cmd_write_srcid_fifo.put_and_get(p_vci_tgt.srcid.read());
5333        m_cmd_write_trdid_fifo.put_and_get(p_vci_tgt.trdid.read());
5334        m_cmd_write_pktid_fifo.put_and_get(p_vci_tgt.pktid.read());
5335        m_cmd_write_data_fifo.put_and_get(p_vci_tgt.wdata.read());
5336        m_cmd_write_be_fifo.put_and_get(p_vci_tgt.be.read());
5337      } else {
5338        m_cmd_write_addr_fifo.simple_put((addr_t)(p_vci_tgt.address.read()));
5339        m_cmd_write_eop_fifo.simple_put(p_vci_tgt.eop.read());
5340        m_cmd_write_srcid_fifo.simple_put(p_vci_tgt.srcid.read());
5341        m_cmd_write_trdid_fifo.simple_put(p_vci_tgt.trdid.read());
5342        m_cmd_write_pktid_fifo.simple_put(p_vci_tgt.pktid.read());
5343        m_cmd_write_data_fifo.simple_put(p_vci_tgt.wdata.read());
5344        m_cmd_write_be_fifo.simple_put(p_vci_tgt.be.read());
5345      }
5346    } else {
5347      if ( cmd_write_fifo_get ) {
5348        m_cmd_write_addr_fifo.simple_get();
5349        m_cmd_write_eop_fifo.simple_get();
5350        m_cmd_write_srcid_fifo.simple_get();
5351        m_cmd_write_trdid_fifo.simple_get();
5352        m_cmd_write_pktid_fifo.simple_get();
5353        m_cmd_write_data_fifo.simple_get();
5354        m_cmd_write_be_fifo.simple_get();
5355      }
5356    }
5357    ////////////////////////////////////////////////////////////////////////////////////
[184]5358    //          TGT_CMD to SC FIFO
[2]5359    ////////////////////////////////////////////////////////////////////////////////////
5360
[184]5361    if ( cmd_sc_fifo_put ) {
5362      if ( cmd_sc_fifo_get ) {
5363        m_cmd_sc_addr_fifo.put_and_get((addr_t)(p_vci_tgt.address.read()));
5364        m_cmd_sc_eop_fifo.put_and_get(p_vci_tgt.eop.read());
5365        m_cmd_sc_srcid_fifo.put_and_get(p_vci_tgt.srcid.read());
5366        m_cmd_sc_trdid_fifo.put_and_get(p_vci_tgt.trdid.read());
5367        m_cmd_sc_pktid_fifo.put_and_get(p_vci_tgt.pktid.read());
5368        m_cmd_sc_wdata_fifo.put_and_get(p_vci_tgt.wdata.read());
[2]5369      } else {
[184]5370        m_cmd_sc_addr_fifo.simple_put((addr_t)(p_vci_tgt.address.read()));
5371        m_cmd_sc_eop_fifo.simple_put(p_vci_tgt.eop.read());
5372        m_cmd_sc_srcid_fifo.simple_put(p_vci_tgt.srcid.read());
5373        m_cmd_sc_trdid_fifo.simple_put(p_vci_tgt.trdid.read());
5374        m_cmd_sc_pktid_fifo.simple_put(p_vci_tgt.pktid.read());
5375        m_cmd_sc_wdata_fifo.simple_put(p_vci_tgt.wdata.read());
[2]5376      }
5377    } else {
[184]5378      if ( cmd_sc_fifo_get ) {
5379        m_cmd_sc_addr_fifo.simple_get();
5380        m_cmd_sc_eop_fifo.simple_get();
5381        m_cmd_sc_srcid_fifo.simple_get();
5382        m_cmd_sc_trdid_fifo.simple_get();
5383        m_cmd_sc_pktid_fifo.simple_get();
5384        m_cmd_sc_wdata_fifo.simple_get();
[2]5385      }
5386    }
5387    ////////////////////////////////////////////////////////////////////////////////////
5388    //          WRITE to INIT_CMD FIFO
5389    ////////////////////////////////////////////////////////////////////////////////////
5390
5391    if ( write_to_init_cmd_fifo_put ) {
5392      if ( write_to_init_cmd_fifo_get ) {
5393        m_write_to_init_cmd_inst_fifo.put_and_get(write_to_init_cmd_fifo_inst);
5394        m_write_to_init_cmd_srcid_fifo.put_and_get(write_to_init_cmd_fifo_srcid);
[140]5395#if L1_MULTI_CACHE
5396        m_write_to_init_cmd_cache_id_fifo.put_and_get(write_to_init_cmd_fifo_cache_id);
5397#endif
[2]5398      } else {
5399        m_write_to_init_cmd_inst_fifo.simple_put(write_to_init_cmd_fifo_inst);
5400        m_write_to_init_cmd_srcid_fifo.simple_put(write_to_init_cmd_fifo_srcid);
[140]5401#if L1_MULTI_CACHE
5402        m_write_to_init_cmd_cache_id_fifo.simple_put(write_to_init_cmd_fifo_cache_id);
5403#endif
[2]5404      }
5405    } else {
5406      if ( write_to_init_cmd_fifo_get ) {
5407        m_write_to_init_cmd_inst_fifo.simple_get();
5408        m_write_to_init_cmd_srcid_fifo.simple_get();
[140]5409#if L1_MULTI_CACHE
5410        m_write_to_init_cmd_cache_id_fifo.simple_get();
5411#endif
[2]5412      }
5413    }
5414    ////////////////////////////////////////////////////////////////////////////////////
5415    //          XRAM_RSP to INIT_CMD FIFO
5416    ////////////////////////////////////////////////////////////////////////////////////
5417
5418    if ( xram_rsp_to_init_cmd_fifo_put ) {
5419      if ( xram_rsp_to_init_cmd_fifo_get ) {
5420        m_xram_rsp_to_init_cmd_inst_fifo.put_and_get(xram_rsp_to_init_cmd_fifo_inst);
5421        m_xram_rsp_to_init_cmd_srcid_fifo.put_and_get(xram_rsp_to_init_cmd_fifo_srcid);
[140]5422#if L1_MULTI_CACHE
5423        m_xram_rsp_to_init_cmd_cache_id_fifo.put_and_get(xram_rsp_to_init_cmd_fifo_cache_id);
5424#endif
[2]5425      } else {
5426        m_xram_rsp_to_init_cmd_inst_fifo.simple_put(xram_rsp_to_init_cmd_fifo_inst);
5427        m_xram_rsp_to_init_cmd_srcid_fifo.simple_put(xram_rsp_to_init_cmd_fifo_srcid);
[140]5428#if L1_MULTI_CACHE
5429        m_xram_rsp_to_init_cmd_cache_id_fifo.simple_put(xram_rsp_to_init_cmd_fifo_cache_id);
5430#endif
[2]5431      }
5432    } else {
5433      if ( xram_rsp_to_init_cmd_fifo_get ) {
5434        m_xram_rsp_to_init_cmd_inst_fifo.simple_get();
5435        m_xram_rsp_to_init_cmd_srcid_fifo.simple_get();
[140]5436#if L1_MULTI_CACHE
5437        m_xram_rsp_to_init_cmd_cache_id_fifo.simple_get();
5438#endif
[2]5439      }
5440    }
5441    ////////////////////////////////////////////////////////////////////////////////////
[184]5442    //          SC to INIT_CMD FIFO
[2]5443    ////////////////////////////////////////////////////////////////////////////////////
5444
[184]5445    if ( sc_to_init_cmd_fifo_put ) {
5446      if ( sc_to_init_cmd_fifo_get ) {
5447        m_sc_to_init_cmd_inst_fifo.put_and_get(sc_to_init_cmd_fifo_inst);
5448        m_sc_to_init_cmd_srcid_fifo.put_and_get(sc_to_init_cmd_fifo_srcid);
[140]5449#if L1_MULTI_CACHE
[184]5450        m_sc_to_init_cmd_cache_id_fifo.put_and_get(sc_to_init_cmd_fifo_cache_id);
[140]5451#endif
[2]5452      } else {
[184]5453          m_sc_to_init_cmd_inst_fifo.simple_put(sc_to_init_cmd_fifo_inst);
5454          m_sc_to_init_cmd_srcid_fifo.simple_put(sc_to_init_cmd_fifo_srcid);
[140]5455#if L1_MULTI_CACHE
[184]5456          m_sc_to_init_cmd_cache_id_fifo.simple_put(sc_to_init_cmd_fifo_cache_id);
[140]5457#endif
[2]5458      }
5459    } else {
[184]5460        if ( sc_to_init_cmd_fifo_get ) {
5461            m_sc_to_init_cmd_inst_fifo.simple_get();
5462            m_sc_to_init_cmd_srcid_fifo.simple_get();
[140]5463#if L1_MULTI_CACHE
[184]5464            m_sc_to_init_cmd_cache_id_fifo.simple_get();
[140]5465#endif
[2]5466      }
5467    }
5468
5469    m_cpt_cycles++;
5470
[184]5471} // end transition()
[2]5472
[184]5473/////////////////////////////
5474tmpl(void)::genMoore()
5475/////////////////////////////
5476{
[2]5477    ////////////////////////////////////////////////////////////
5478    // Command signals on the p_vci_ixr port
5479    ////////////////////////////////////////////////////////////
5480
5481    p_vci_ixr.be      = 0xF;
5482    p_vci_ixr.pktid   = 0;
5483    p_vci_ixr.srcid   = m_srcid_ixr;
5484    p_vci_ixr.cons    = false;
5485    p_vci_ixr.wrap    = false;
5486    p_vci_ixr.contig  = true;
5487    p_vci_ixr.clen    = 0;
5488    p_vci_ixr.cfixed  = false;
5489
5490    if ( r_ixr_cmd_fsm.read() == IXR_CMD_READ_NLINE ) {
5491      p_vci_ixr.cmd     = vci_param::CMD_READ;
5492      p_vci_ixr.cmdval  = true;
5493      p_vci_ixr.address = (addr_t)(r_read_to_ixr_cmd_nline.read()*m_words*4);
5494      p_vci_ixr.plen    = m_words*4;
5495      p_vci_ixr.wdata   = 0x00000000;
5496      p_vci_ixr.trdid   = r_read_to_ixr_cmd_trdid.read();
5497      p_vci_ixr.eop     = true;
5498    }
[184]5499    else if ( r_ixr_cmd_fsm.read() == IXR_CMD_SC_NLINE ) {
5500      if(r_sc_to_ixr_cmd_write.read()){
[2]5501        p_vci_ixr.cmd     = vci_param::CMD_WRITE;
5502        p_vci_ixr.cmdval  = true;
[184]5503        p_vci_ixr.address = (addr_t)((r_sc_to_ixr_cmd_nline.read()*m_words+r_ixr_cmd_cpt.read())*4);
[2]5504        p_vci_ixr.plen    = m_words*4;
[184]5505        p_vci_ixr.wdata   = r_sc_to_ixr_cmd_data[r_ixr_cmd_cpt.read()].read();
5506        p_vci_ixr.trdid   = r_sc_to_ixr_cmd_trdid.read();
[2]5507        p_vci_ixr.eop     = (r_ixr_cmd_cpt == (m_words-1));
5508      } else {
5509        p_vci_ixr.cmd     = vci_param::CMD_READ;
5510        p_vci_ixr.cmdval  = true;
[184]5511        p_vci_ixr.address = (addr_t)(r_sc_to_ixr_cmd_nline.read()*m_words*4);
[2]5512        p_vci_ixr.plen    = m_words*4;
5513        p_vci_ixr.wdata   = 0x00000000;
[184]5514        p_vci_ixr.trdid   = r_sc_to_ixr_cmd_trdid.read();
[2]5515        p_vci_ixr.eop     = true;
5516      }
5517    }
5518    else if ( r_ixr_cmd_fsm.read() == IXR_CMD_WRITE_NLINE ) {
5519      if(r_write_to_ixr_cmd_write.read()){
5520        p_vci_ixr.cmd     = vci_param::CMD_WRITE;
5521        p_vci_ixr.cmdval  = true;
5522        p_vci_ixr.address = (addr_t)((r_write_to_ixr_cmd_nline.read()*m_words+r_ixr_cmd_cpt.read())*4);
5523        p_vci_ixr.plen    = m_words*4;
5524        p_vci_ixr.wdata   = r_write_to_ixr_cmd_data[r_ixr_cmd_cpt.read()].read();
5525        p_vci_ixr.trdid   = r_write_to_ixr_cmd_trdid.read();
5526        p_vci_ixr.eop     = (r_ixr_cmd_cpt == (m_words-1));
5527      } else {
5528        p_vci_ixr.cmd     = vci_param::CMD_READ;
5529        p_vci_ixr.cmdval  = true;
5530        p_vci_ixr.address = (addr_t)(r_write_to_ixr_cmd_nline.read()*m_words*4);
5531        p_vci_ixr.plen    = m_words*4;
5532        p_vci_ixr.wdata   = 0x00000000;
5533        p_vci_ixr.trdid   = r_write_to_ixr_cmd_trdid.read();
5534        p_vci_ixr.eop     = true;
5535      }
5536    }
5537    else if ( r_ixr_cmd_fsm.read() == IXR_CMD_XRAM_DATA ) {
5538      p_vci_ixr.cmd     = vci_param::CMD_WRITE;
5539      p_vci_ixr.cmdval  = true;
5540      p_vci_ixr.address = (addr_t)((r_xram_rsp_to_ixr_cmd_nline.read()*m_words+r_ixr_cmd_cpt.read())*4);
5541      p_vci_ixr.plen    = m_words*4;
5542      p_vci_ixr.wdata   = r_xram_rsp_to_ixr_cmd_data[r_ixr_cmd_cpt.read()].read();
5543      p_vci_ixr.trdid   = r_xram_rsp_to_ixr_cmd_trdid.read();
5544      p_vci_ixr.eop     = (r_ixr_cmd_cpt == (m_words-1));
5545    } else {
5546      p_vci_ixr.cmdval  = false;
5547      p_vci_ixr.address = 0;
5548      p_vci_ixr.plen    = 0;
5549      p_vci_ixr.wdata   = 0;
5550      p_vci_ixr.trdid   = 0;
5551      p_vci_ixr.eop     = false;
5552    }
5553
5554    ////////////////////////////////////////////////////
5555    // Response signals on the p_vci_ixr port
5556    ////////////////////////////////////////////////////
5557
5558    if ( ((r_alloc_trt_fsm.read() == ALLOC_TRT_IXR_RSP) &&
5559          (r_ixr_rsp_fsm.read() == IXR_RSP_TRT_READ)) ||
5560        (r_ixr_rsp_fsm.read() == IXR_RSP_ACK) ) p_vci_ixr.rspack = true;
5561    else                                        p_vci_ixr.rspack = false;
5562
5563    ////////////////////////////////////////////////////
5564    // Command signals on the p_vci_tgt port
5565    ////////////////////////////////////////////////////
5566
5567    switch ((tgt_cmd_fsm_state_e)r_tgt_cmd_fsm.read()) {
5568      case TGT_CMD_IDLE:
5569        p_vci_tgt.cmdack  = false;
5570        break;
5571      case TGT_CMD_READ:
5572        p_vci_tgt.cmdack  = m_cmd_read_addr_fifo.wok();
5573        break;
5574      case TGT_CMD_WRITE:
5575        p_vci_tgt.cmdack  = m_cmd_write_addr_fifo.wok();
5576        break;
5577      case TGT_CMD_ATOMIC:
[184]5578        p_vci_tgt.cmdack  = m_cmd_sc_addr_fifo.wok();
[2]5579        break;
5580      default:
5581        p_vci_tgt.cmdack = false;
5582        break;
5583    }
5584
5585    ////////////////////////////////////////////////////
5586    // Response signals on the p_vci_tgt port
5587    ////////////////////////////////////////////////////
5588    switch ( r_tgt_rsp_fsm.read() ) {
5589
5590      case TGT_RSP_READ_IDLE:
5591      case TGT_RSP_WRITE_IDLE:
[184]5592      case TGT_RSP_SC_IDLE:
[2]5593      case TGT_RSP_XRAM_IDLE:
5594      case TGT_RSP_INIT_IDLE:
5595      case TGT_RSP_CLEANUP_IDLE:
5596        p_vci_tgt.rspval  = false;
5597        p_vci_tgt.rsrcid  = 0;
5598        p_vci_tgt.rdata   = 0;
5599        p_vci_tgt.rpktid  = 0;
5600        p_vci_tgt.rtrdid  = 0;
5601        p_vci_tgt.rerror  = 0;
5602        p_vci_tgt.reop    = false;     
5603        break;
5604      case TGT_RSP_READ:
5605        p_vci_tgt.rspval   = true;
5606        p_vci_tgt.rdata    = r_read_to_tgt_rsp_data[r_tgt_rsp_cpt.read()].read();
5607        p_vci_tgt.rsrcid   = r_read_to_tgt_rsp_srcid.read();
5608        p_vci_tgt.rtrdid   = r_read_to_tgt_rsp_trdid.read();
5609        p_vci_tgt.rpktid   = r_read_to_tgt_rsp_pktid.read();
5610        p_vci_tgt.rerror   = 0;
5611        p_vci_tgt.reop     = ( r_tgt_rsp_cpt.read() == (r_read_to_tgt_rsp_word.read()+r_read_to_tgt_rsp_length-1) );
5612        break;
5613      case TGT_RSP_WRITE:
5614        p_vci_tgt.rspval   = true;
5615        p_vci_tgt.rdata    = 0;
5616        p_vci_tgt.rsrcid   = r_write_to_tgt_rsp_srcid.read();
5617        p_vci_tgt.rtrdid   = r_write_to_tgt_rsp_trdid.read();
5618        p_vci_tgt.rpktid   = r_write_to_tgt_rsp_pktid.read();
[184]5619        p_vci_tgt.rerror   = 0x2 & ( (1 << vci_param::E) - 1);
[2]5620        p_vci_tgt.reop     = true;
5621        break;
5622      case TGT_RSP_CLEANUP:
5623        p_vci_tgt.rspval   = true;
5624        p_vci_tgt.rdata    = 0;
5625        p_vci_tgt.rsrcid   = r_cleanup_to_tgt_rsp_srcid.read();
5626        p_vci_tgt.rtrdid   = r_cleanup_to_tgt_rsp_trdid.read();
5627        p_vci_tgt.rpktid   = r_cleanup_to_tgt_rsp_pktid.read();
[82]5628        p_vci_tgt.rerror   = 0; // Can be a SC rsp
[2]5629        p_vci_tgt.reop     = true;
5630        break;
[184]5631      case TGT_RSP_SC:
[2]5632        p_vci_tgt.rspval   = true;
[184]5633        p_vci_tgt.rdata    = r_sc_to_tgt_rsp_data.read();
5634        p_vci_tgt.rsrcid   = r_sc_to_tgt_rsp_srcid.read();
5635        p_vci_tgt.rtrdid   = r_sc_to_tgt_rsp_trdid.read();
5636        p_vci_tgt.rpktid   = r_sc_to_tgt_rsp_pktid.read();
[2]5637        p_vci_tgt.rerror   = 0;
5638        p_vci_tgt.reop     = true;
5639        break;
5640      case TGT_RSP_XRAM:
5641        p_vci_tgt.rspval   = true;
5642        p_vci_tgt.rdata    = r_xram_rsp_to_tgt_rsp_data[r_tgt_rsp_cpt.read()].read();
5643        p_vci_tgt.rsrcid   = r_xram_rsp_to_tgt_rsp_srcid.read();
5644        p_vci_tgt.rtrdid   = r_xram_rsp_to_tgt_rsp_trdid.read();
5645        p_vci_tgt.rpktid   = r_xram_rsp_to_tgt_rsp_pktid.read();
[138]5646        p_vci_tgt.rerror   = r_xram_rsp_to_tgt_rsp_rerror.read();
[184]5647        p_vci_tgt.reop     = (( r_tgt_rsp_cpt.read()
5648                                == (r_xram_rsp_to_tgt_rsp_word.read()+r_xram_rsp_to_tgt_rsp_length.read()-1))
[138]5649                              || r_xram_rsp_to_tgt_rsp_rerror.read());
[2]5650        break;
5651      case TGT_RSP_INIT:
5652        p_vci_tgt.rspval   = true;
5653        p_vci_tgt.rdata    = 0;
5654        p_vci_tgt.rsrcid   = r_init_rsp_to_tgt_rsp_srcid.read();
5655        p_vci_tgt.rtrdid   = r_init_rsp_to_tgt_rsp_trdid.read();
5656        p_vci_tgt.rpktid   = r_init_rsp_to_tgt_rsp_pktid.read();
[82]5657        p_vci_tgt.rerror   = 0; // Can be a SC rsp
[2]5658        p_vci_tgt.reop     = true;     
5659        break;
5660    } // end switch r_tgt_rsp_fsm
5661
5662    ///////////////////////////////////////////////////
5663    // Command signals on the p_vci_ini port
5664    ///////////////////////////////////////////////////
5665
5666    p_vci_ini.cmd     = vci_param::CMD_WRITE;
5667    p_vci_ini.srcid   = m_srcid_ini;
5668    p_vci_ini.cons    = true;
5669    p_vci_ini.wrap    = false;
5670    p_vci_ini.contig  = false;
5671    p_vci_ini.clen    = 0;
5672    p_vci_ini.cfixed  = false;
5673
5674    switch ( r_init_cmd_fsm.read() ) {
5675
5676      case INIT_CMD_UPDT_IDLE:
5677      case INIT_CMD_INVAL_IDLE:
5678      case INIT_CMD_SC_UPDT_IDLE:
5679        p_vci_ini.cmdval  = false;
5680        p_vci_ini.address = 0;
5681        p_vci_ini.wdata   = 0;
5682        p_vci_ini.be      = 0;
5683        p_vci_ini.plen    = 0;
5684        p_vci_ini.trdid   = 0;
[140]5685        p_vci_ini.pktid   = 0;
[2]5686        p_vci_ini.eop     = false;
5687        break;
5688      case INIT_CMD_INVAL_NLINE:
[140]5689      {
[2]5690        p_vci_ini.cmdval  = m_xram_rsp_to_init_cmd_inst_fifo.rok();
5691        if(m_xram_rsp_to_init_cmd_inst_fifo.rok()){
5692          if(m_xram_rsp_to_init_cmd_inst_fifo.read()) {
5693            p_vci_ini.address = (addr_t)(m_coherence_table[m_xram_rsp_to_init_cmd_srcid_fifo.read()]+4);
5694          } else {
5695            p_vci_ini.address = (addr_t)(m_coherence_table[m_xram_rsp_to_init_cmd_srcid_fifo.read()]);
5696          }
5697        } else p_vci_ini.address = 0; // prevent segmentation faults by reading an empty fifo
5698        p_vci_ini.wdata   = (uint32_t)r_xram_rsp_to_init_cmd_nline.read();
5699        p_vci_ini.be      = ((r_xram_rsp_to_init_cmd_nline.read() >> 32) & 0x3);
5700        p_vci_ini.plen    = 4;
5701        p_vci_ini.trdid   = r_xram_rsp_to_init_cmd_trdid.read();
[140]5702        p_vci_ini.pktid   = m_xram_rsp_to_init_cmd_cache_id_fifo.read();
[2]5703        p_vci_ini.eop     = true;
5704        break;
[140]5705      }
[2]5706      case INIT_CMD_XRAM_BRDCAST:
5707        p_vci_ini.cmdval  = true;
[116]5708        p_vci_ini.address = m_broadcast_address;
[2]5709        p_vci_ini.wdata   = (uint32_t)r_xram_rsp_to_init_cmd_nline.read();
5710        p_vci_ini.be      = ((r_xram_rsp_to_init_cmd_nline.read() >> 32) & 0x3);
5711        p_vci_ini.plen    = 4;
5712        p_vci_ini.trdid   = r_xram_rsp_to_init_cmd_trdid.read();
[140]5713        p_vci_ini.pktid   = 0;
[2]5714        p_vci_ini.eop     = true;
5715        break;
5716
5717      case INIT_CMD_WRITE_BRDCAST:
5718        p_vci_ini.cmdval  = true;
[116]5719        p_vci_ini.address = m_broadcast_address;
[2]5720        p_vci_ini.wdata   = (addr_t)r_write_to_init_cmd_nline.read();
5721        p_vci_ini.be      = ((r_write_to_init_cmd_nline.read() >> 32) & 0x3);
5722        p_vci_ini.plen    = 4 ;
5723        p_vci_ini.eop     = true;
5724        p_vci_ini.trdid   = r_write_to_init_cmd_trdid.read();
[140]5725        p_vci_ini.pktid   = 0;
[2]5726        break;
5727      case INIT_CMD_UPDT_NLINE:
5728        p_vci_ini.cmdval  = m_write_to_init_cmd_inst_fifo.rok();
5729        if(m_write_to_init_cmd_inst_fifo.rok()){
5730          if(m_write_to_init_cmd_inst_fifo.read()) {
5731            p_vci_ini.address = (addr_t)(m_coherence_table[m_write_to_init_cmd_srcid_fifo.read()] + 12);
5732          } else {
5733            p_vci_ini.address = (addr_t)(m_coherence_table[m_write_to_init_cmd_srcid_fifo.read()] + 8);
5734          }
5735        } else {
5736          p_vci_ini.address = 0;
5737        }
5738        p_vci_ini.wdata   = (uint32_t)r_write_to_init_cmd_nline.read();
5739        p_vci_ini.be      = ((r_write_to_init_cmd_nline.read() >> 32 ) & 0x3);
5740        p_vci_ini.plen    = 4 * (r_write_to_init_cmd_count.read() + 2);
5741        p_vci_ini.eop     = false;
5742        p_vci_ini.trdid   = r_write_to_init_cmd_trdid.read();
[140]5743        p_vci_ini.pktid   = m_write_to_init_cmd_cache_id_fifo.read();
[2]5744        break;
5745      case INIT_CMD_UPDT_INDEX:
5746        p_vci_ini.cmdval  = true;
5747        if(m_write_to_init_cmd_inst_fifo.read()) {
5748          p_vci_ini.address = (addr_t)(m_coherence_table[m_write_to_init_cmd_srcid_fifo.read()] + 12);
5749        } else {
5750          p_vci_ini.address = (addr_t)(m_coherence_table[m_write_to_init_cmd_srcid_fifo.read()] + 8);
5751        }
5752        p_vci_ini.wdata   = r_write_to_init_cmd_index.read();
5753        p_vci_ini.be      = 0xF;
5754        p_vci_ini.plen    = 4 * (r_write_to_init_cmd_count.read() + 2);
5755        p_vci_ini.trdid   = r_write_to_init_cmd_trdid.read();
[140]5756        p_vci_ini.pktid   = m_write_to_init_cmd_cache_id_fifo.read();
[2]5757        p_vci_ini.eop     = false;
5758        break;
5759      case INIT_CMD_UPDT_DATA:
5760        p_vci_ini.cmdval  = true;
5761        if(m_write_to_init_cmd_inst_fifo.read()) {
5762          p_vci_ini.address = (addr_t)(m_coherence_table[m_write_to_init_cmd_srcid_fifo.read()] + 12);
5763        } else {
5764          p_vci_ini.address = (addr_t)(m_coherence_table[m_write_to_init_cmd_srcid_fifo.read()] + 8);
5765        }
5766        p_vci_ini.wdata   = r_write_to_init_cmd_data[r_init_cmd_cpt.read() +
5767          r_write_to_init_cmd_index.read()].read();
5768        p_vci_ini.be      = r_write_to_init_cmd_be[r_init_cmd_cpt.read() +
5769            r_write_to_init_cmd_index.read()].read()  ;
5770        p_vci_ini.plen    = 4 * (r_write_to_init_cmd_count.read() + 2);
5771        p_vci_ini.trdid   = r_write_to_init_cmd_trdid.read();
[140]5772        p_vci_ini.pktid   = m_write_to_init_cmd_cache_id_fifo.read();
[2]5773        p_vci_ini.eop     = ( r_init_cmd_cpt.read() == (r_write_to_init_cmd_count.read()-1) );
5774        break;
5775
5776      case INIT_CMD_SC_BRDCAST:
5777        p_vci_ini.cmdval  = true;
[116]5778        p_vci_ini.address = m_broadcast_address;
[184]5779        p_vci_ini.wdata   = (addr_t)r_sc_to_init_cmd_nline.read();
5780        p_vci_ini.be      = ((r_sc_to_init_cmd_nline.read() >> 32) & 0x3);
[2]5781        p_vci_ini.plen    = 4 ;
5782        p_vci_ini.eop     = true;
[184]5783        p_vci_ini.trdid   = r_sc_to_init_cmd_trdid.read();
[140]5784        p_vci_ini.pktid   = 0;
[2]5785        break;
5786      case INIT_CMD_SC_UPDT_NLINE:
[184]5787        p_vci_ini.cmdval  = m_sc_to_init_cmd_inst_fifo.rok();
5788        if(m_sc_to_init_cmd_inst_fifo.rok()){
5789          if( m_sc_to_init_cmd_inst_fifo.read() ) {
5790            p_vci_ini.address = (addr_t)(m_coherence_table[m_sc_to_init_cmd_srcid_fifo.read()] + 12);
[2]5791          } else {
[184]5792            p_vci_ini.address = (addr_t)(m_coherence_table[m_sc_to_init_cmd_srcid_fifo.read()] + 8);
[2]5793          }
5794        } else {
5795          p_vci_ini.address = 0;
5796        }
[184]5797        p_vci_ini.wdata   = (uint32_t)r_sc_to_init_cmd_nline.read();
5798        p_vci_ini.be      = ((r_sc_to_init_cmd_nline.read() >> 32 ) & 0x3);
5799        if(r_sc_to_init_cmd_is_long.read()){
[2]5800            p_vci_ini.plen    = 4 * 4;
5801        } else {
5802            p_vci_ini.plen    = 4 * 3;
5803        }
5804        p_vci_ini.eop     = false;
[184]5805        p_vci_ini.trdid   = r_sc_to_init_cmd_trdid.read();
5806        p_vci_ini.pktid   = m_sc_to_init_cmd_cache_id_fifo.read();
[2]5807        break;
5808      case INIT_CMD_SC_UPDT_INDEX:
5809        p_vci_ini.cmdval  = true;
[184]5810        if( m_sc_to_init_cmd_inst_fifo.read() ) {
5811          p_vci_ini.address = (addr_t)(m_coherence_table[m_sc_to_init_cmd_srcid_fifo.read()] + 12);
[2]5812        } else {
[184]5813          p_vci_ini.address = (addr_t)(m_coherence_table[m_sc_to_init_cmd_srcid_fifo.read()] + 8);
[2]5814        }
[184]5815        p_vci_ini.wdata   = r_sc_to_init_cmd_index.read();
[2]5816        p_vci_ini.be      = 0xF;
[184]5817        if(r_sc_to_init_cmd_is_long.read()){
[2]5818            p_vci_ini.plen    = 4 * 4;
5819        } else {
5820            p_vci_ini.plen    = 4 * 3;
5821        }
[184]5822        p_vci_ini.trdid   = r_sc_to_init_cmd_trdid.read();
5823        p_vci_ini.pktid   = m_sc_to_init_cmd_cache_id_fifo.read();
[2]5824        p_vci_ini.eop     = false;
5825        break;
5826      case INIT_CMD_SC_UPDT_DATA:
5827        p_vci_ini.cmdval  = true;
[184]5828        if( m_sc_to_init_cmd_inst_fifo.read() ) {
5829          p_vci_ini.address = (addr_t)(m_coherence_table[m_sc_to_init_cmd_srcid_fifo.read()] + 12);
[2]5830        } else {
[184]5831          p_vci_ini.address = (addr_t)(m_coherence_table[m_sc_to_init_cmd_srcid_fifo.read()] + 8);
[2]5832        }
[184]5833        p_vci_ini.wdata   = r_sc_to_init_cmd_wdata.read();
[2]5834        p_vci_ini.be      = 0xF;
[184]5835        p_vci_ini.trdid   = r_sc_to_init_cmd_trdid.read();
5836        p_vci_ini.pktid   = m_sc_to_init_cmd_cache_id_fifo.read();
5837        if(r_sc_to_init_cmd_is_long.read()){
[2]5838            p_vci_ini.plen    = 4 * 4;
5839            p_vci_ini.eop     = false;
5840        } else {
5841            p_vci_ini.plen    = 4 * 3;
5842            p_vci_ini.eop     = true;
5843        }
5844        break;
5845      case INIT_CMD_SC_UPDT_DATA_HIGH:
5846        p_vci_ini.cmdval  = true;
[184]5847        if( m_sc_to_init_cmd_inst_fifo.read() ) {
5848          p_vci_ini.address = (addr_t)(m_coherence_table[m_sc_to_init_cmd_srcid_fifo.read()] + 12);
[2]5849        } else {
[184]5850          p_vci_ini.address = (addr_t)(m_coherence_table[m_sc_to_init_cmd_srcid_fifo.read()] + 8);
[2]5851        }
[184]5852        p_vci_ini.wdata   = r_sc_to_init_cmd_wdata_high.read();
[2]5853        p_vci_ini.be      = 0xF;
5854        p_vci_ini.plen    = 4 * 4;
[184]5855        p_vci_ini.trdid   = r_sc_to_init_cmd_trdid.read();
5856        p_vci_ini.pktid   = m_sc_to_init_cmd_cache_id_fifo.read();
[2]5857        p_vci_ini.eop     = true;
5858        break;
5859
5860    } // end switch r_init_cmd_fsm
5861
5862    //////////////////////////////////////////////////////
5863    // Response signals on the p_vci_ini port
5864    //////////////////////////////////////////////////////
5865
5866    if ( r_init_rsp_fsm.read() == INIT_RSP_IDLE ) p_vci_ini.rspack  = true;
5867    else                                          p_vci_ini.rspack  = false;
5868
5869    //////////////////////////////////////////////////////
5870    // Response signals on the p_vci_tgt_cleanup port
5871    //////////////////////////////////////////////////////
5872    p_vci_tgt_cleanup.rspval = false;
5873    p_vci_tgt_cleanup.rsrcid = 0;
5874    p_vci_tgt_cleanup.rdata  = 0;
5875    p_vci_tgt_cleanup.rpktid = 0;
5876    p_vci_tgt_cleanup.rtrdid = 0;
5877    p_vci_tgt_cleanup.rerror = 0;
5878    p_vci_tgt_cleanup.reop   = false;
5879    p_vci_tgt_cleanup.cmdack = false ;
5880
5881    switch(r_cleanup_fsm.read()){
5882      case CLEANUP_IDLE:
5883        {
5884          p_vci_tgt_cleanup.cmdack = true ;
5885          break;
5886        }
5887      case CLEANUP_RSP:
5888        {
5889          p_vci_tgt_cleanup.rspval = true;
5890          p_vci_tgt_cleanup.rdata  = 0;
5891          p_vci_tgt_cleanup.rsrcid = r_cleanup_srcid.read();
5892          p_vci_tgt_cleanup.rpktid = r_cleanup_pktid.read();
5893          p_vci_tgt_cleanup.rtrdid = r_cleanup_trdid.read();
[83]5894          p_vci_tgt_cleanup.rerror = 0x2 & ( (1 << vci_param::E) - 1);
[2]5895          p_vci_tgt_cleanup.reop   = 1;
5896          break;
5897        }
5898
5899    }
5900
[184]5901} // end genMoore()
[2]5902
5903}} // end name space
5904
5905// Local Variables:
[141]5906// tab-width: 2
5907// c-basic-offset: 2
[2]5908// c-file-offsets:((innamespace . 0)(inline-open . 0))
5909// indent-tabs-mode: nil
5910// End:
5911
5912// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
5913
Note: See TracBrowser for help on using the repository browser.