source: trunk/modules/vci_cc_xcache_wrapper_v4/caba/source/src/vci_cc_xcache_wrapper_v4.cpp @ 161

Last change on this file since 161 was 161, checked in by alain, 13 years ago

bug fix (line 2385)

  • 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: 124.0 KB
Line 
1/* -*- c++ -*-
2 *
3 * SOCLIB_LGPL_HEADER_BEGIN
4 *
5 * This file is part of SoCLib, GNU LGPLv2.1.
6 *
7 * SoCLib is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU Lesser General Public License as published
9 * by the Free Software Foundation; version 2.1 of the License.
10 *
11 * SoCLib is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with SoCLib; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 * 02110-1301 USA
20 *
21 * SOCLIB_LGPL_HEADER_END
22 *
23 * Copyright (c) UPMC, Lip6, SoC
24 *         Alain Greiner <alain.greiner@lip6.fr>, 2008
25 *
26 * Maintainers: alain eric.guthmuller@polytechnique.edu nipo
27 */
28
29/////////////////////////////////////////////////////////////////////////////
30// History
31// - 25/04/2008
32//   The existing vci_xcache component has been extended to include
33//   a VCI target port to support a directory based coherence protocol.
34//   Two types of packets can be send by the L2 cache to the L1 cache
35//   * INVALIDATE packets : length = 1
36//   * UPDATE packets : length = n + 2   
37//   The CLEANUP packets are sent by the L1 cache to the L2 cache,
38//   to signal a replaced cache line.
39// - 12/08/2008
40//   The vci_cc_xcache_wrapper component instanciates directly the processsor
41//   iss, in order to supress the processor/cache interface.
42//   According to the VCI advanced specification, this component uses one
43//   word VCI CMD packets for MISS transactions, and accept one word VCI RSP
44//   packets for Write burst  transactions.
45//   The write buffer has been modified to use the WriteBuffer object.
46//   A VCI write burst is constructed when two conditions are satisfied :
47//   The processor make strictly successive write requests, and they are
48//   in the same cache line. The write buffer performs re-ordering, to
49//   respect the contiguous addresses VCI constraint. In case of several
50//   WRITE_WORD requests in the same word, only the last request is conserved.
51//   In case of several WRITE_HALF or WRITE_WORD requests in the same word,
52//   the requests are merged in the same word. In case of uncached write
53//   requests, each request is transmited as a single VCI transaction.
54//   Both the data & instruction caches can be flushed in one single cycle.
55///////////////////////////////////////////////////////////////////////////////
56
57#include <cassert>
58#include <iomanip>
59#include "arithmetics.h"
60#include "../include/vci_cc_xcache_wrapper_v4.h"
61
62#if CC_XCACHE_WRAPPER_DEBUG
63# define PRINTF(msg...) do { if (m_cpt_total_cycles>=CC_XCACHE_WRAPPER_DEBUG_CYCLE_MIN) printf(msg); } while (0);
64#else
65# define PRINTF(msg...)
66#endif
67
68# define ASSERT(cond,msg) assert ((cond) and msg);
69
70#if CC_XCACHE_WRAPPER_FIFO_RSP
71# define CACHE_MISS_BUF_ALLOC
72# define CACHE_MISS_BUF_DEALLOC
73# define CACHE_MISS_BUF_RESET(c)        while (r_##c##cache_miss_buf.size()>0) {r_##c##cache_miss_buf.pop();}
74# define CACHE_MISS_BUF_REQ_INIT(c)
75# define CACHE_MISS_BUF_RSP_VAL(c,n)    (r_##c##cache_miss_buf.size()>0)
76# define CACHE_MISS_BUF_RSP_ACK(c)      (r_##c##cache_miss_buf.size()<2)
77# define CACHE_MISS_BUF_RSP_DATA(c,n)   r_##c##cache_miss_buf.front()
78# define CACHE_MISS_BUF_RSP_POP(c)      do { r_##c##cache_miss_buf.pop();} while (0)
79# define CACHE_MISS_BUF_RSP_PUSH(c,n,d) do { r_##c##cache_miss_buf.push(d);} while (0)
80# define CACHE_MISS_BUF_RSP_PRINT(c)    do { PRINTF("    * cache_miss_buf - size : %d\n",r_##c##cache_miss_buf.size());} while (0)
81#else
82# define CACHE_MISS_BUF_ALLOC           do { \
83                                        r_icache_miss_val = new bool  [m_icache_words]; \
84                                        r_icache_miss_buf = new data_t[m_icache_words]; \
85                                        r_dcache_miss_val = new bool  [m_dcache_words]; \
86                                        r_dcache_miss_buf = new data_t[m_dcache_words]; \
87                                        } while (0)
88# define CACHE_MISS_BUF_DEALLOC         do { \
89                                        delete [] r_icache_miss_val; \
90                                        delete [] r_icache_miss_buf; \
91                                        delete [] r_dcache_miss_val; \
92                                        delete [] r_dcache_miss_buf; \
93                                        } while (0)
94# define CACHE_MISS_BUF_RESET(c)
95# define CACHE_MISS_BUF_REQ_INIT(c)     do {for (uint32_t i=0; i<m_##c##cache_words;++i) r_##c##cache_miss_val[i] = false;} while (0)
96# define CACHE_MISS_BUF_RSP_VAL(c,n)    r_##c##cache_miss_val[n]
97# define CACHE_MISS_BUF_RSP_ACK(c)      true
98# define CACHE_MISS_BUF_RSP_DATA(c,n)   r_##c##cache_miss_buf[n]
99# define CACHE_MISS_BUF_RSP_POP(c)
100# define CACHE_MISS_BUF_RSP_PUSH(c,n,d) do {r_##c##cache_miss_val[n] = true; r_##c##cache_miss_buf[n] = d;} while (0)
101# define CACHE_MISS_BUF_RSP_PRINT(c)    do {for (uint32_t i=0; i<m_##c##cache_words;++i) PRINTF("%d %x |",r_##c##cache_miss_val[i],r_##c##cache_miss_buf[i]); PRINTF("\n");} while (0)
102#endif
103
104namespace soclib {
105namespace caba {
106    namespace {
107
108        const char *dcache_fsm_state_str[] = {
109            "DCACHE_IDLE",
110            "DCACHE_WRITE_UPDT",
111#if CC_XCACHE_WRAPPER_SELECT_VICTIM
112            "DCACHE_MISS_VICTIM",
113#endif
114            "DCACHE_MISS_WAIT",
115            "DCACHE_MISS_UPDT",
116            "DCACHE_UNC_WAIT",
117            "DCACHE_SC_WAIT",
118            "DCACHE_INVAL",
119            "DCACHE_SYNC",
120            "DCACHE_ERROR",
121            "DCACHE_CC_CHECK",
122            "DCACHE_CC_INVAL",
123            "DCACHE_CC_UPDT",
124            "DCACHE_CC_CLEANUP",
125        };
126        const char *icache_fsm_state_str[] = {
127            "ICACHE_IDLE",
128#if CC_XCACHE_WRAPPER_SELECT_VICTIM
129            "ICACHE_MISS_VICTIM",
130#endif
131            "ICACHE_MISS_WAIT",
132            "ICACHE_MISS_UPDT",
133            "ICACHE_UNC_WAIT",
134            "ICACHE_ERROR",
135            "ICACHE_CC_CLEANUP",
136            "ICACHE_CC_CHECK",
137            "ICACHE_CC_INVAL",
138            "ICACHE_CC_UPDT",
139        };
140        const char *cmd_fsm_state_str[] = {
141            "CMD_IDLE",
142            "CMD_INS_MISS",
143            "CMD_INS_UNC",
144            "CMD_DATA_MISS",
145            "CMD_DATA_UNC",
146            "CMD_DATA_WRITE",
147            "CMD_DATA_SC",
148        };
149        const char *rsp_fsm_state_str[] = {
150            "RSP_IDLE",
151            "RSP_INS_MISS",
152            "RSP_INS_UNC",
153            "RSP_DATA_MISS",
154            "RSP_DATA_UNC",
155            "RSP_DATA_WRITE",
156            "RSP_DATA_SC",
157        };
158        const char *tgt_fsm_state_str[] = {
159            "TGT_IDLE",
160            "TGT_UPDT_WORD",
161            "TGT_UPDT_DATA",
162            "TGT_REQ_BROADCAST",
163            "TGT_REQ_ICACHE",
164            "TGT_REQ_DCACHE",
165            "TGT_RSP_BROADCAST",
166            "TGT_RSP_ICACHE",
167            "TGT_RSP_DCACHE",
168        };
169
170        const char *cleanup_fsm_state_str[] = {
171            "CLEANUP_IDLE",
172            "CLEANUP_DCACHE",
173            "CLEANUP_ICACHE",
174        };
175    }
176
177#define tmpl(...)  template<typename vci_param, typename iss_t> __VA_ARGS__ VciCcXCacheWrapperV4<vci_param, iss_t>
178
179    using soclib::common::uint32_log2;
180
181    /////////////////////////////////
182    tmpl(/**/)::VciCcXCacheWrapperV4(
183    /////////////////////////////////
184            sc_module_name name,
185            int proc_id,
186            const soclib::common::MappingTable &mtp,
187            const soclib::common::MappingTable &mtc,
188            const soclib::common::IntTab &initiator_index_rw,
189            const soclib::common::IntTab &initiator_index_c,
190            const soclib::common::IntTab &target_index,
191            size_t icache_ways,
192            size_t icache_sets,
193            size_t icache_words,
194            size_t dcache_ways,
195            size_t dcache_sets,
196            size_t dcache_words,
197            size_t wbuf_nwords,
198            size_t wbuf_nlines,
199            size_t wbuf_timeout
200                                     )
201        :
202            soclib::caba::BaseModule(name),
203
204            p_clk       ("clk"),
205            p_resetn    ("resetn"),
206            p_vci_ini_rw("vci_ini_rw"),
207            p_vci_ini_c ("vci_ini_c"),
208            p_vci_tgt   ("vci_tgt"),
209
210            m_cacheability_table(mtp.getCacheabilityTable<vci_addr_t>()),
211            m_segment(mtc.getSegment(target_index)),
212            m_iss(this->name(), proc_id),
213            m_srcid_rw(mtp.indexForId(initiator_index_rw)),
214            m_srcid_c(mtc.indexForId(initiator_index_c)),
215
216            m_dcache_ways(dcache_ways),
217            m_dcache_words(dcache_words),
218            m_dcache_words_shift(uint32_log2(dcache_words)+2),
219            m_dcache_yzmask((~0)<<m_dcache_words_shift),
220            m_icache_ways(icache_ways),
221            m_icache_words(icache_words),
222            m_icache_words_shift(uint32_log2(icache_words)+2),
223            m_icache_yzmask((~0)<<m_icache_words_shift),
224            m_cache_words((dcache_words)?dcache_words:icache_words),
225
226            r_dcache_fsm("r_dcache_fsm"),
227            r_dcache_fsm_save("r_dcache_fsm_save"),
228            r_dcache_addr_save("r_dcache_addr_save"),
229            r_dcache_wdata_save("r_dcache_wdata_save"),
230            r_dcache_rdata_save("r_dcache_rdata_save"),
231            r_dcache_type_save("r_dcache_type_save"),
232            r_dcache_be_save("r_dcache_be_save"),
233            r_dcache_cached_save("r_dcache_cached_save"),
234            r_dcache_cleanup_req("r_dcache_cleanup_req"),
235            r_dcache_cleanup_line("r_dcache_cleanup_line"),
236            r_dcache_miss_req("r_dcache_miss_req"),
237            r_dcache_miss_way("r_dcache_miss_way"),
238            r_dcache_miss_set("r_dcache_miss_set"),
239            r_dcache_unc_req("r_dcache_unc_req"),
240            r_dcache_sc_req("r_dcache_sc_req"),
241            r_dcache_inval_rsp("r_dcache_inval_rsp"),
242            r_dcache_update_addr("r_dcache_update_addr"),
243            r_dcache_ll_data("r_dcache_ll_data"),
244            r_dcache_ll_addr("r_dcache_ll_addr"),
245            r_dcache_ll_valid("r_dcache_ll_valid"),
246            r_dcache_previous_unc("r_dcache_previous_unc"),
247
248            r_icache_fsm("r_icache_fsm"),
249            r_icache_fsm_save("r_icache_fsm_save"),
250            r_icache_addr_save("r_icache_addr_save"),
251            r_icache_miss_req("r_icache_miss_req"),
252            r_icache_miss_way("r_icache_miss_way"),
253            r_icache_miss_set("r_icache_miss_set"),
254            r_icache_unc_req("r_icache_unc_req"),
255            r_icache_cleanup_req("r_icache_cleanup_req"),
256            r_icache_cleanup_line("r_icache_cleanup_line"),
257            r_icache_inval_rsp("r_icache_inval_rsp"),
258            r_icache_update_addr("r_icache_update_addr"),
259
260            r_vci_cmd_fsm("r_vci_cmd_fsm"),
261            r_vci_cmd_min("r_vci_cmd_min"),
262            r_vci_cmd_max("r_vci_cmd_max"),
263            r_vci_cmd_cpt("r_vci_cmd_cpt"),
264            r_vci_cmd_dcache_prior("r_vci_cmd_dcache_prior"),
265
266            r_vci_rsp_fsm("r_vci_rsp_fsm"),
267            r_vci_rsp_ins_error("r_vci_rsp_ins_error"),
268            r_vci_rsp_data_error("r_vci_rsp_data_error"),
269            r_vci_rsp_cpt("r_vci_rsp_cpt"),
270            r_vci_rsp_ack("r_vci_rsp_ack"),
271
272            r_icache_buf_unc_valid("r_icache_buf_unc_valid"),
273
274#if CC_XCACHE_WRAPPER_CC_UPDATE_MULTI_CYCLE
275            r_cache_word("r_cache_word"),
276#endif
277
278            r_vci_tgt_fsm("r_vci_tgt_fsm"),
279            r_tgt_addr("r_tgt_addr"),
280            r_tgt_word("r_tgt_word"),
281            r_tgt_update("r_tgt_update"),
282            r_tgt_update_data("r_tgt_update_data"),
283         // r_tgt_brdcast("r_tgt_brdcast"),
284            r_tgt_srcid("r_tgt_srcid"),
285            r_tgt_pktid("r_tgt_pktid"),
286            r_tgt_trdid("r_tgt_trdid"),
287         // r_tgt_plen("r_tgt_plen"),
288            r_tgt_icache_req("r_tgt_icache_req"),
289            r_tgt_dcache_req("r_tgt_dcache_req"),
290            r_tgt_icache_rsp("r_tgt_icache_rsp"),
291            r_tgt_dcache_rsp("r_tgt_dcache_rsp"),
292
293            r_cleanup_fsm("r_cleanup_fsm"),
294
295            r_wbuf("r_wbuf", wbuf_nwords, wbuf_nlines, wbuf_timeout, dcache_words),
296            r_icache("icache", icache_ways, icache_sets, icache_words),
297            r_dcache("dcache", dcache_ways, dcache_sets, dcache_words)
298            {
299                // Size of word is 32 bits
300                ASSERT( (icache_words*vci_param::B) < (1<<vci_param::K),
301                        "I need more PLEN bits");
302
303                ASSERT( (vci_param::T > 2) and ((1<<(vci_param::T-1)) >= wbuf_nlines),
304                        "I need more TRDID bits");
305
306                CACHE_MISS_BUF_ALLOC;
307
308                r_tgt_buf = new data_t[m_cache_words];
309                r_tgt_be  = new be_t  [m_cache_words];
310
311                SC_METHOD(transition);
312                dont_initialize();
313                sensitive << p_clk.pos();
314
315                SC_METHOD(genMoore);
316                dont_initialize();
317                sensitive << p_clk.neg();
318
319
320                typename iss_t::CacheInfo cache_info;
321                cache_info.has_mmu          = false;
322                cache_info.icache_line_size = icache_words*sizeof(data_t);
323                cache_info.icache_assoc     = icache_ways;
324                cache_info.icache_n_lines   = icache_sets;
325                cache_info.dcache_line_size = dcache_words*sizeof(data_t);
326                cache_info.dcache_assoc     = dcache_ways;
327                cache_info.dcache_n_lines   = dcache_sets;
328                m_iss.setCacheInfo(cache_info);
329
330#if CC_XCACHE_WRAPPER_STOP_SIMULATION
331                m_stop_simulation               = false;
332                m_stop_simulation_nb_frz_cycles = 0;
333#endif // CC_XCACHE_WRAPPER_STOP_SIMULATION
334
335#if CC_XCACHE_WRAPPER_DEBUG_DCACHE_TRANSACTION
336                std::ostringstream filename("");
337                filename << "Instruction_flow_" << proc_id << ".log";
338               
339                log_dcache_transaction_file.open(filename.str().c_str() ,std::ios::out | std::ios::trunc);
340#endif
341            } // end constructor
342
343    ///////////////////////////////////
344    tmpl(/**/)::~VciCcXCacheWrapperV4()
345    ///////////////////////////////////
346    {
347#if CC_XCACHE_WRAPPER_DEBUG_DCACHE_TRANSACTION
348        log_dcache_transaction_file.close();
349#endif
350
351        delete [] r_tgt_buf;
352        delete [] r_tgt_be ;
353
354        CACHE_MISS_BUF_DEALLOC;
355    }
356
357    ////////////////////////
358    tmpl(void)::print_cpi()
359    ////////////////////////
360    {
361        std::cout << "CPU " << m_srcid_rw << " : CPI = "
362            << (float)m_cpt_total_cycles/(m_cpt_total_cycles - m_cpt_frz_cycles) << std::endl ;
363    }
364    ////////////////////////
365    tmpl(void)::print_stats()
366    ////////////////////////
367    {
368        float run_cycles = (float)(m_cpt_total_cycles - m_cpt_frz_cycles);
369
370        uint32_t m_cpt_data_read_cached  = m_cpt_data_read-m_cpt_data_read_uncached;
371        uint32_t m_cpt_data_write_cached = m_cpt_data_write-m_cpt_data_write_uncached;
372        std::cout << "------------------------------------" << std:: dec << std::endl;
373        std::cout << "CPU " << m_srcid_rw << " / Time = " << m_cpt_total_cycles << std::endl;
374        std::cout << "- CPI                            : " << (float)m_cpt_total_cycles/run_cycles << std::endl ;
375        std::cout << "- IPC                            : " << (float)run_cycles/m_cpt_total_cycles << std::endl ;
376        std::cout << "- DATA READ *                    : " << m_cpt_data_read << std::endl ;
377        std::cout << "  + Uncached                     : " << m_cpt_data_read_uncached << " (" << (float)m_cpt_data_read_uncached*100.0/(float)m_cpt_data_read << "%)" << std::endl ;
378        std::cout << "  + Cached and miss              : " << m_cpt_data_read_miss << " (" << (float)m_cpt_data_read_miss*100.0/(float)m_cpt_data_read_cached << "%)" << std::endl;
379        std::cout << "- DATA WRITE *                   : " << m_cpt_data_write << std::endl ;
380        std::cout << "  + Uncached                     : " << m_cpt_data_write_uncached << " (" << (float)m_cpt_data_write_uncached*100.0/(float)m_cpt_data_write << "%)" << std::endl ;
381        std::cout << "  + Cached and miss              : " << m_cpt_data_write_miss << " (" << (float)m_cpt_data_write_miss*100.0/(float)m_cpt_data_write_cached << "%)" << std::endl;
382        // std::cout << "- WRITE RATE                     : " << (float)m_cpt_data_write/run_cycles << std::endl;
383        // std::cout << "- UNCACHED READ RATE             : " << (float)m_cpt_data_read_uncached/m_cpt_data_read << std::endl ;
384        // std::cout << "- CACHED WRITE RATE              : " << (float)m_cpt_data_write_cached/m_cpt_data_write << std::endl ;
385        // std::cout << "- IMISS_RATE                     : " << (float)m_cpt_ins_miss/run_cycles << std::endl;
386        // std::cout << "- DMISS RATE                     : " << (float)m_cpt_data_miss/(m_cpt_data_read-m_cpt_data_read_uncached) << std::endl ;
387        // std::cout << "- INS MISS COST                  : " << (float)m_cost_ins_miss_frz/m_cpt_ins_miss << std::endl;
388        // std::cout << "- IMISS TRANSACTION              : " << (float)m_cost_imiss_transaction/m_cpt_imiss_transaction << std::endl;
389        // std::cout << "- DMISS COST                     : " << (float)m_cost_data_miss_frz/m_cpt_data_miss << std::endl;
390        // std::cout << "- DMISS TRANSACTION              : " << (float)m_cost_dmiss_transaction/m_cpt_dmiss_transaction << std::endl;
391        // std::cout << "- UNC COST                       : " << (float)m_cost_unc_read_frz/m_cpt_data_read_uncached << std::endl;
392        // std::cout << "- UNC TRANSACTION                : " << (float)m_cost_unc_transaction/m_cpt_unc_transaction << std::endl;
393        // std::cout << "- WRITE COST                     : " << (float)m_cost_write_frz/m_cpt_data_write << std::endl;
394        // std::cout << "- WRITE TRANSACTION              : " << (float)m_cost_write_transaction/m_cpt_data_write_transaction << std::endl;
395        // std::cout << "- WRITE LENGTH                   : " << (float)m_length_write_transaction/m_cpt_data_write_transaction << std::endl;
396
397        std::cout << "- CC_UPDATE_ICACHE               : " << m_cpt_cc_update_icache  << std::endl;
398        std::cout << "  + AVERAGE WORD USEFUL          : " << (float)m_cpt_cc_update_icache_word_useful/(float)m_cpt_cc_update_icache << " on " << m_icache_words << " words" << std::endl;
399        std::cout << "- CC_UPDATE_DCACHE               : " << m_cpt_cc_update_dcache  << std::endl;
400        std::cout << "  + AVERAGE WORD USEFUL          : " << (float)m_cpt_cc_update_dcache_word_useful/(float)m_cpt_cc_update_dcache << " on " << m_dcache_words << " words" << std::endl;
401        uint32_t m_cpt_cc_inval = m_cpt_cc_inval_broadcast+m_cpt_cc_inval_icache+m_cpt_cc_inval_dcache;
402        std::cout << "- CC_INVALID                     : " << m_cpt_cc_inval << std::endl;
403        std::cout << "  + ICACHE Only                  : " << (float)m_cpt_cc_inval_icache   *100.0/(float)m_cpt_cc_inval << "%" << std::endl;
404        std::cout << "  + DCACHE Only                  : " << (float)m_cpt_cc_inval_dcache   *100.0/(float)m_cpt_cc_inval << "%" << std::endl;
405        std::cout << "  + BROADCAST                    : " << (float)m_cpt_cc_inval_broadcast*100.0/(float)m_cpt_cc_inval << "%" << std::endl;
406        std::cout << "* : accepted or not by the cache" << std::endl ;
407
408        r_wbuf.printStatistics();
409    }
410
411    ////////////////////////////////////
412    tmpl(void)::print_trace(size_t mode)
413    ////////////////////////////////////
414    {
415        // b0 : write buffer print trace
416        // b1 : write buffer verbose
417        // b2 : dcache print trace
418        // b3 : icache print trace
419
420        typename iss_t::InstructionRequest  ireq;
421        typename iss_t::DataRequest         dreq;
422
423        m_iss.getRequests( ireq, dreq );
424        std::cout << std::dec << "Proc \"" << name() << "\"" << std::endl;
425        std::cout << ireq << std::endl;
426        std::cout << dreq << std::endl;
427        std::cout << "  " << dcache_fsm_state_str[r_dcache_fsm]
428                  << "  " << icache_fsm_state_str[r_icache_fsm]
429                  << "  " << cmd_fsm_state_str[r_vci_cmd_fsm]
430                  << "  " << rsp_fsm_state_str[r_vci_rsp_fsm]
431                  << "  " << tgt_fsm_state_str[r_vci_tgt_fsm]
432                  << "  " << cleanup_fsm_state_str[r_cleanup_fsm] << std::endl;
433
434        if(mode & 0x1)
435        {
436            r_wbuf.printTrace((mode>>1)&1);
437        }
438        if(mode & 0x4)
439        {
440            std::cout << "  Data cache" << std::endl;
441            r_dcache.printTrace();
442        }
443        if(mode & 0x8)
444        {
445            std::cout << "  Instruction cache" << std::endl;
446            r_icache.printTrace();
447        }
448
449        // if(mode & 0x10)
450        // {
451        //     std::cout << "  Icache miss buffer : ";
452        //     CACHE_MISS_BUF_RSP_PRINT(i);
453        //     std::cout << std::endl;
454
455        //     std::cout << "  Dcache miss buffer : ";
456        //     CACHE_MISS_BUF_RSP_PRINT(d);
457        //     std::cout << std::endl;
458        // }
459    }
460
461    //////////////////////////
462    tmpl(void)::transition()
463    //////////////////////////
464    {
465        if ( not p_resetn.read() ) {
466
467            m_iss.reset();
468
469            // FSM states
470            r_dcache_fsm  = DCACHE_IDLE;
471            r_icache_fsm  = ICACHE_IDLE;
472            r_vci_cmd_fsm = CMD_IDLE;
473            r_vci_rsp_fsm = RSP_IDLE;
474            r_vci_tgt_fsm = TGT_IDLE;
475            r_cleanup_fsm = CLEANUP_IDLE;
476
477            // write buffer & caches
478            r_wbuf.reset();
479            r_icache.reset();
480            r_dcache.reset();
481
482            // synchronisation flip-flops from ICACHE & DCACHE FSMs to VCI  FSMs
483            r_icache_miss_req    = false;
484            r_icache_unc_req     = false;
485            r_icache_cleanup_req = false;
486            r_dcache_miss_req    = false;
487            r_dcache_unc_req     = false;
488            r_dcache_sc_req      = false;
489            r_dcache_cleanup_req = false;
490            r_dcache_previous_unc= false;
491
492            // synchronisation flip-flops from TGT FSM to ICACHE & DCACHE FSMs
493            r_tgt_icache_req     = false;
494            r_tgt_dcache_req     = false;
495            r_tgt_icache_rsp     = false;
496            r_tgt_dcache_rsp     = false;
497
498#if CC_XCACHE_WRAPPER_CC_UPDATE_MULTI_CYCLE
499            r_cache_word         = 0;
500#endif
501
502
503            // internal messages in DCACHE et ICACHE FSMs
504            r_icache_inval_rsp   = false;
505            r_dcache_inval_rsp   = false;
506
507            // error signals from the VCI RSP FSM to the ICACHE or DCACHE FSMs
508            r_dcache_ll_valid      = false;
509            r_icache_buf_unc_valid = false;
510
511            r_vci_cmd_dcache_prior = false;
512
513            r_vci_rsp_data_error   = false;
514            r_vci_rsp_ins_error    = false;
515
516            CACHE_MISS_BUF_RESET(i);
517            CACHE_MISS_BUF_RESET(d);
518
519            // activity counters
520            m_cpt_dcache_data_read  = 0;
521            m_cpt_dcache_data_write = 0;
522            m_cpt_dcache_dir_read   = 0;
523            m_cpt_dcache_dir_write  = 0;
524            m_cpt_icache_data_read  = 0;
525            m_cpt_icache_data_write = 0;
526            m_cpt_icache_dir_read   = 0;
527            m_cpt_icache_dir_write  = 0;
528
529            m_cpt_cc_update_icache             = 0;
530            m_cpt_cc_update_dcache             = 0;
531            m_cpt_cc_inval_broadcast           = 0;
532            m_cpt_cc_inval_icache              = 0;
533            m_cpt_cc_inval_dcache              = 0;
534            m_cpt_cc_update_icache_word_useful = 0;
535            m_cpt_cc_update_dcache_word_useful = 0;
536
537            m_cpt_frz_cycles   = 0;
538            m_cpt_total_cycles = 0;
539
540            m_cpt_data_read            = 0;
541            m_cpt_data_read_miss       = 0;
542            m_cpt_data_read_uncached   = 0;
543            m_cpt_data_write           = 0;
544            m_cpt_data_write_miss      = 0;
545            m_cpt_data_write_uncached  = 0;
546
547            m_cpt_ins_miss     = 0;
548
549            m_cost_write_frz = 0;
550            m_cost_data_miss_frz = 0;
551            m_cost_unc_read_frz = 0;
552            m_cost_ins_miss_frz = 0;
553
554            m_cpt_imiss_transaction = 0;
555            m_cpt_dmiss_transaction = 0;
556            m_cpt_unc_transaction = 0;
557            m_cpt_data_write_transaction = 0;
558
559            m_cost_imiss_transaction = 0;
560            m_cost_dmiss_transaction = 0;
561            m_cost_unc_transaction = 0;
562            m_cost_write_transaction = 0;
563            m_length_write_transaction = 0;
564
565            return;
566        }
567
568        // printf("%d\n",(uint32_t)m_cpt_total_cycles);
569
570        PRINTF("--------------------------------------------\n");
571        PRINTF("  * CC_XCACHE_WRAPPER \"%s\" - Time = %d\n",name().c_str(),(uint32_t)m_cpt_total_cycles);
572        PRINTF("    * fsm dcache          = %s\n",dcache_fsm_state_str[r_dcache_fsm]);
573        PRINTF("    * fsm icache          = %s\n",icache_fsm_state_str[r_icache_fsm]);
574        PRINTF("    * fsm cmd             = %s\n",cmd_fsm_state_str[r_vci_cmd_fsm]);
575        PRINTF("    * fsm rsp             = %s\n",rsp_fsm_state_str[r_vci_rsp_fsm]);
576        PRINTF("    * fsm tgt             = %s\n",tgt_fsm_state_str[r_vci_tgt_fsm]);
577        PRINTF("    * fsm cleanup         = %s\n",cleanup_fsm_state_str[r_cleanup_fsm]);
578        PRINTF("    * ll info             : %d %llx %llx\n",r_dcache_ll_valid.read(), (uint64_t)r_dcache_ll_addr.read(), (uint64_t)r_dcache_ll_data.read());
579        PRINTF("    * dcache_previous_unc : %d\n",r_dcache_previous_unc.read());
580        // CACHE_MISS_BUF_RSP_PRINT(i);
581        // CACHE_MISS_BUF_RSP_PRINT(d);
582
583#if CC_XCACHE_WRAPPER_DEBUG
584        if (m_cpt_total_cycles>=CC_XCACHE_WRAPPER_DEBUG_CYCLE_MIN)
585            {
586                r_wbuf.printTrace(1);
587            }
588#endif
589
590        m_cpt_total_cycles++;
591
592        /////////////////////////////////////////////////////////////////////
593        // The TGT_FSM controls the following ressources:
594        // - r_vci_tgt_fsm
595        // - r_tgt_buf[nwords]
596        // - r_tgt_be[nwords]
597        // - r_tgt_update
598        // - r_tgt_word
599        // - r_tgt_addr
600        // - r_tgt_srcid
601        // - r_tgt_trdid
602        // - r_tgt_pktid
603        // All VCI commands must be CMD_WRITE.
604        // If the VCI address offset is null, the command is an invalidate
605        // request. It is an update request otherwise.
606        // The VCI_TGT FSM stores the external request arguments in the
607        // IDLE, UPDT_WORD & UPDT_DATA states. It sets the r_tgt_icache_req
608        // & r_tgt_dcache_req flip-flops to signal the external request to
609        // the ICACHE & DCACHE FSMs in the REQ state. It waits the completion
610        // of the update or invalidate request in the RSP state.
611        // -  for an invalidate request the VCI packet length is 1 word.
612        // The WDATA field contains the line index (i.e. the Z & Y fields).
613        // -  for an update request the VCI packet length is (n+2) words.
614        // The WDATA field of the first VCI word contains the line number.
615        // The WDATA field of the second VCI word contains the word index.
616        // The WDATA field of the n following words contains the values.
617        // -  for both invalidate & update requests, the VCI response
618        // is one single word.
619        // In case of errors in the VCI command packet, the simulation
620        // is stopped with an error message.
621        /////////////////////////////////////////////////////////////////////
622
623        switch(r_vci_tgt_fsm) {
624
625            case TGT_IDLE:
626                if ( p_vci_tgt.cmdval.read() )
627                {
628                    PRINTF("    * <TGT> request\n");
629
630                    addr_40 address = p_vci_tgt.address.read();
631
632                    if ( p_vci_tgt.cmd.read() != vci_param::CMD_WRITE)
633                    {
634                        std::cout << "error in component VCI_CC_XCACHE_WRAPPER " << name() << std::endl;
635                        std::cout << "coherence request is not a write" << std::endl;
636                        std::cout << "oddress = " << std::hex << address << std::dec << std::endl;
637                        std::cout << "srcid   = " << p_vci_tgt.srcid.read() << std::endl;
638                        exit(0);
639                    }
640
641                    // multi-update or multi-invalidate for data type
642                    if ( ((address&0x3) != 0x3) and (not m_segment.contains(address)) )
643                    {
644                        std::cout << "error in component VCI_CC_XCACHE_WRAPPER " << name() << std::endl;
645                        std::cout << "out of segment coherence request" << std::endl;
646                        std::cout << "oddress = " << std::hex << address << std::dec << std::endl;
647                        std::cout << "srcid   = " << p_vci_tgt.srcid.read() << std::endl;
648                        exit(0);
649                    }
650
651                    r_tgt_addr = (((addr_40) ((p_vci_tgt.be.read() & 0x3) << 32)) |
652                                 ((addr_40) (p_vci_tgt.wdata.read()))) * m_dcache_words * 4;     
653                    r_tgt_srcid = p_vci_tgt.srcid.read();
654                    r_tgt_trdid = p_vci_tgt.trdid.read();
655                    r_tgt_pktid = p_vci_tgt.pktid.read();
656                 // r_tgt_plen  = p_vci_tgt.plen.read();
657                   
658                    PRINTF("    * <TGT> address : %llx\n",(uint64_t)address);
659                    PRINTF("    * <TGT> address : %llx\n",(uint64_t)((((addr_40) ((p_vci_tgt.be.read() & 0x3) << 32)) |
660                                                                      ((addr_40) (p_vci_tgt.wdata.read()))) * m_dcache_words * 4));
661
662                    if ( (address&0x3) == 0x3 )   // broadcast invalidate for data or instruction type
663                    {
664                        if ( not p_vci_tgt.eop.read() )
665                        {
666                            std::cout << "error in component VCI_CC_XCACHE_WRAPPER " << name() << std::endl;
667                            std::cout << "the BROADCAST INVALIDATE command length must be one word" << std::endl;
668                            exit(0);
669                        }
670                        r_tgt_update = false;
671                        // r_tgt_brdcast= true;
672                        r_vci_tgt_fsm = TGT_REQ_BROADCAST;
673                        m_cpt_cc_inval_broadcast++ ;
674                    }
675                    else                    // multi-update or multi-invalidate for data type
676                    {
677                        uint32_t cell = address - m_segment.baseAddress(); // addr_40
678                        // r_tgt_brdcast = false;
679                        if (cell == 0)
680                        {                                       // invalidate data
681                            if ( not p_vci_tgt.eop.read() )
682                            {
683                                std::cout << "error in component VCI_CC_XCACHE_WRAPPER " << name() << std::endl;
684                                std::cout << "the MULTI-INVALIDATE command length must be one word" << std::endl;
685                                exit(0);
686                            }
687                            r_tgt_update = false;
688                            r_vci_tgt_fsm = TGT_REQ_DCACHE;
689                            m_cpt_cc_inval_dcache++ ;
690                        }
691                        else if (cell == 4)                     // invalidate instruction
692                        {                         
693                            if ( not p_vci_tgt.eop.read() )
694                            {
695                                std::cout << "error in component VCI_CC_VCACHE_WRAPPER " << name() << std::endl;
696                                std::cout << "the MULTI-INVALIDATE command length must be one word" << std::endl;
697                                exit(0);
698                            }
699                            r_tgt_update = false;
700                            r_vci_tgt_fsm = TGT_REQ_ICACHE;
701                            m_cpt_cc_inval_icache++ ;
702                        }
703                        else if ( (cell == 8) or (cell==12) )    // update data or instruction
704                        {                               
705                            if ( p_vci_tgt.eop.read() )
706                            {
707                                std::cout << "error in component VCI_CC_VCACHE_WRAPPER " << name() << std::endl;
708                                std::cout << "the MULTI-UPDATE command length must be N+2 words" << std::endl;
709                                exit(0);
710                            }
711                            if(cell == 8)
712                            {
713                                m_cpt_cc_update_dcache++;
714                                r_tgt_update_data = true;
715                            }
716                            else
717                            {
718                                m_cpt_cc_update_icache++;
719                                r_tgt_update_data = false;
720                            }
721                            r_tgt_update = true;
722                            r_vci_tgt_fsm = TGT_UPDT_WORD;
723                        }
724
725                    } // end if address
726                } // end if cmdval
727                break;
728
729            case TGT_UPDT_WORD:
730                if (p_vci_tgt.cmdval.read())
731                {
732                    if ( p_vci_tgt.eop.read() )
733                    {
734                        std::cout << "error in component VCI_CC_XCACHE_WRAPPER " << name() << std::endl;
735                        std::cout << "the MULTI-UPDATE command length must be N+2 words" << std::endl;
736                        exit(0);
737                    }
738                    for ( size_t i=0 ; i<m_dcache_words ; i++ ) r_tgt_be[i] = 0;
739                    r_tgt_word = p_vci_tgt.wdata.read(); // the first modified word index
740#ifdef COHERENCE_DEBUG
741                    std::cout << "PROC " << m_srcid_rw << " update, line : " << std::hex << r_tgt_addr.read() << " word : " << p_vci_tgt.wdata.read() << std::dec << std::endl;
742#endif
743                    r_vci_tgt_fsm = TGT_UPDT_DATA;
744                }
745                break;
746
747            case TGT_UPDT_DATA:
748                if (p_vci_tgt.cmdval.read())
749                {
750                    size_t word = r_tgt_word.read();
751                    if ( word >= m_cache_words )
752                    {
753                        std::cout << "error in component VCI_CC_XCACHE_WRAPPER " << name() << std::endl;
754                        std::cout << "the reveived MULTI-UPDATE command length is wrong" << std::endl;
755                        exit(0);
756                    }
757#ifdef COHERENCE_DEBUG
758                    std::cout << "PROC " << m_srcid_rw << " update, data : " << p_vci_tgt.wdata.read() << " be : " << std::hex << p_vci_tgt.be.read() << std::dec << std::endl;
759#endif
760
761                    r_tgt_buf[word] = p_vci_tgt.wdata.read();
762                    r_tgt_be [word] = p_vci_tgt.be.read();
763
764                    if (p_vci_tgt.be.read())
765                    {
766                        if(r_tgt_update_data.read())
767                            m_cpt_cc_update_dcache_word_useful++ ;
768                        else
769                            m_cpt_cc_update_icache_word_useful++ ;
770                    }
771
772                    r_tgt_word = word + 1;
773                    if (p_vci_tgt.eop.read()){
774#if CC_XCACHE_WRAPPER_CC_UPDATE_MULTI_CYCLE_OPT
775                      uint32_t word=0;
776                      for (; word<m_cache_words; ++word)
777                          if (r_tgt_be[word] != 0)
778                              break;
779                      r_cache_word = word;
780#endif
781                      if(r_tgt_update_data.read()){
782                        r_vci_tgt_fsm = TGT_REQ_DCACHE;
783                      } else {
784                        r_vci_tgt_fsm = TGT_REQ_ICACHE;
785                      }
786                    }
787                }
788                break;
789
790            case TGT_REQ_BROADCAST:
791                if ( not r_tgt_icache_req.read() and not r_tgt_dcache_req.read() )
792                {
793                    r_vci_tgt_fsm = TGT_RSP_BROADCAST;
794                    r_tgt_icache_req = true;
795                    r_tgt_dcache_req = true;
796                }
797                break;
798                ////////////////////
799            case TGT_REQ_ICACHE:
800                {
801                    if ( not r_tgt_icache_req.read() )
802                    {
803                        r_vci_tgt_fsm = TGT_RSP_ICACHE;
804                        r_tgt_icache_req = true;
805                    }
806                    break;
807                }
808
809            case TGT_REQ_DCACHE:
810                if ( not r_tgt_dcache_req.read() )
811                {
812                    r_vci_tgt_fsm = TGT_RSP_DCACHE;
813                    r_tgt_dcache_req = true;
814                }
815                break;
816
817            case TGT_RSP_BROADCAST:
818                if ( not r_tgt_icache_req.read() and not r_tgt_dcache_req.read() )
819                {
820                    // one response
821                    if ( not r_tgt_icache_rsp or not r_tgt_dcache_rsp )
822                    {
823                        if ( p_vci_tgt.rspack.read() )
824                        {
825                            r_vci_tgt_fsm = TGT_IDLE;
826                            r_tgt_icache_rsp = false;
827                            r_tgt_dcache_rsp = false;
828                        }
829                    }
830
831                    // if data and instruction have the inval line, need two responses 
832                    if ( r_tgt_icache_rsp and r_tgt_dcache_rsp )
833                    {
834                        if ( p_vci_tgt.rspack.read() )
835                        {
836                            r_tgt_icache_rsp = false; // only reset one for respond the second time
837                        }
838                    }
839
840                    // if there is no need for a response
841                    if ( not r_tgt_icache_rsp and not r_tgt_dcache_rsp )
842                    {
843                        r_vci_tgt_fsm = TGT_IDLE;
844                    }
845
846                }
847                break;
848                ////////////////////
849            case TGT_RSP_ICACHE:
850                {
851                    if ( (p_vci_tgt.rspack.read() or not r_tgt_icache_rsp.read()) and not r_tgt_icache_req.read() )
852                    {
853                        r_vci_tgt_fsm = TGT_IDLE;
854                        r_tgt_icache_rsp = false;
855                    }
856                    break;
857                }
858
859            case TGT_RSP_DCACHE:
860                {
861                    if ( (p_vci_tgt.rspack.read() or not r_tgt_dcache_rsp.read()) and not r_tgt_dcache_req.read() )
862                    {
863                        r_vci_tgt_fsm = TGT_IDLE;
864                        r_tgt_dcache_rsp = false;
865                    }
866                    break;
867                }
868        } // end switch TGT_FSM
869
870        /////////////////////////////////////////////////////////////////////
871        // The ICACHE FSM controls the following ressources:
872        // - r_icache_fsm
873        // - r_icache_fsm_save
874        // - r_icache instruction cache access
875        // - r_icache_addr_save
876        // - r_icache_miss_req set
877        // - r_icache_unc_req set
878        // - r_icache_buf_unc_valid set
879        // - r_vci_rsp_icache_miss_ok reset
880        // - r_vci_rsp_ins_error reset
881        // - r_tgt_icache_req reset
882        // - ireq & irsp structures for communication with the processor
883        //
884        // 1/ External requests (update or invalidate) have highest priority.
885        //    They are taken into account in the IDLE and WAIT states.
886        //    As external hit should be extremly rare on the ICACHE,
887        //    all external requests are handled as invalidate...
888        //    In case of external request the ICACHE FSM goes to the CC_CHECK
889        //    state to test the external hit, and returns in the
890        //    pre-empted state after completion.
891        // 2/ Processor requests are taken into account only in the IDLE state.
892        //    In case of MISS, or in case of uncached instruction, the FSM
893        //    writes the missing address line in the  r_icache_addr_save register
894        //    and sets the r_icache_miss_req or the r_icache_unc_req flip-flops.
895        //    These request flip-flops are reset by the VCI_RSP FSM
896        //    when the VCI transaction is completed and the r_icache_buf_unc_valid
897        //    is set in case of uncached access.
898        //    In case of bus error, the VCI_RSP FSM sets the r_vci_rsp_ins_error
899        //    flip-flop. It is reset by the ICACHE FSM.
900        ///////////////////////////////////////////////////////////////////////
901
902        typename iss_t::InstructionRequest  ireq = ISS_IREQ_INITIALIZER;
903        typename iss_t::InstructionResponse irsp = ISS_IRSP_INITIALIZER;
904
905        typename iss_t::DataRequest         dreq = ISS_DREQ_INITIALIZER;
906        typename iss_t::DataResponse        drsp = ISS_DRSP_INITIALIZER;
907
908        m_iss.getRequests( ireq, dreq );
909
910#if CC_XCACHE_WRAPPER_DEBUG
911        if (m_cpt_total_cycles>=CC_XCACHE_WRAPPER_DEBUG_CYCLE_MIN)
912            std::cout << "    * Instruction Request  : " << ireq << std::endl;
913#endif
914
915        switch(r_icache_fsm) {
916            /////////////////
917            case ICACHE_IDLE:
918                {
919                    if ( r_tgt_icache_req ) {   // external request
920                        if ( ireq.valid ) m_cost_ins_miss_frz++;
921                        r_icache_fsm = ICACHE_CC_CHECK;
922                        r_icache_fsm_save = r_icache_fsm.read();
923                        break;
924                    }
925                    if ( ireq.valid ) {
926                        data_t  icache_ins = 0;
927                        bool    icache_hit = false;
928                        bool    icache_cached = m_cacheability_table[(vci_addr_t)ireq.addr];
929                        bool    icache_cleanup_hit = r_icache_cleanup_req and (((addr_40)ireq.addr >> (addr_40)m_icache_words_shift) == r_icache_cleanup_line.read());
930
931                        // icache_hit & icache_ins evaluation
932                        if ( icache_cached ) {
933                            icache_hit = r_icache.read((vci_addr_t) ireq.addr, &icache_ins);
934                        } else {
935                            // if uncache, again in the icache_miss_buf
936                            icache_hit = ( r_icache_buf_unc_valid and ((addr_40) ireq.addr == (addr_40)r_icache_addr_save));
937                            icache_ins = CACHE_MISS_BUF_RSP_DATA(i,0);
938                            CACHE_MISS_BUF_RSP_POP(i);
939                        }
940
941                        PRINTF("    * <ICACHE> hit %d - cached %d - cleanup_hit %d\n",icache_hit, icache_cached, icache_cleanup_hit);
942
943                        ASSERT( not (icache_hit and icache_cleanup_hit),
944                                "Icache hit and icache_cleanup_hit");
945
946                        if ( not icache_hit and not icache_cleanup_hit) {
947                            m_cpt_ins_miss++;
948                            m_cost_ins_miss_frz++;
949                            r_icache_addr_save = (addr_40) ireq.addr;
950
951                            CACHE_MISS_BUF_REQ_INIT(i);
952
953                            if ( icache_cached ) {
954#if CC_XCACHE_WRAPPER_SELECT_VICTIM
955                                r_icache_fsm = ICACHE_MISS_VICTIM;
956#else
957                                r_icache_fsm = ICACHE_MISS_WAIT;
958#endif
959                                r_icache_miss_req = true;
960                               
961                            } else {
962                                r_icache_fsm = ICACHE_UNC_WAIT;
963                                r_icache_unc_req = true;
964                            }
965                        } else {
966                            r_icache_buf_unc_valid = false;
967                        }
968                        m_cpt_icache_dir_read += m_icache_ways;
969                        m_cpt_icache_data_read += m_icache_ways;
970                        irsp.valid          = icache_hit;
971                        irsp.instruction    = icache_ins;
972                    }
973                    break;
974                }
975                //////////////////////
976#if CC_XCACHE_WRAPPER_SELECT_VICTIM
977            case ICACHE_MISS_VICTIM:
978                {
979                    if (not r_icache_cleanup_req)
980                    {
981                        size_t     way;
982                        size_t     set;
983                        vci_addr_t addr = (vci_addr_t) r_icache_addr_save.read();
984                        vci_addr_t victim;
985                       
986                        r_icache_cleanup_req  = r_icache.victim_select(addr, &victim, &way, &set );
987                        r_icache_cleanup_line = (addr_40) victim;
988                        r_icache_miss_way     = way;
989                        r_icache_miss_set     = set;
990                       
991                        r_icache_fsm = ICACHE_MISS_WAIT;
992                    }
993                    break;
994                }
995#endif
996                //////////////////////
997            case ICACHE_MISS_WAIT:
998                {
999                    m_cost_ins_miss_frz++;
1000                    if ( r_tgt_icache_req ) {   // external request
1001                        r_icache_fsm = ICACHE_CC_CHECK;
1002                        r_icache_fsm_save = r_icache_fsm.read();
1003                        break;
1004                    }
1005
1006                    bool val = CACHE_MISS_BUF_RSP_VAL(i,0);
1007
1008                    PRINTF("    * <ICACHE> val                  : %d\n",val);
1009
1010                    if (val)
1011                    {
1012                        PRINTF("    * <ICACHE> r_icache_inval_rsp   : %d\n",(int) r_icache_inval_rsp  );
1013                        PRINTF("    * <ICACHE> r_vci_rsp_ins_error  : %d\n",(int) r_vci_rsp_ins_error );
1014                        PRINTF("    * <ICACHE> r_icache_cleanup_req : %d\n",(int) r_icache_cleanup_req);
1015
1016                        // if (not r_icache_inval_rsp )
1017                        // {
1018                            // Miss read response and no invalidation
1019                            if ( r_vci_rsp_ins_error ) {
1020                                r_icache_fsm = ICACHE_ERROR;
1021                            } else {
1022#if not CC_XCACHE_WRAPPER_SELECT_VICTIM
1023                                if (not r_icache_cleanup_req.read())
1024#endif
1025                                {
1026                                    r_icache_update_addr = 0;
1027                                    r_icache_fsm         = ICACHE_MISS_UPDT;
1028                                }
1029                            }
1030                        // }
1031                        // else
1032                        // {
1033                        //     r_icache_inval_rsp = false;
1034                           
1035                        //     // Miss read response and invalidation
1036                        //     if ( r_vci_rsp_ins_error )
1037                        //         r_icache_fsm = ICACHE_ERROR;
1038                        //     else
1039                        //         r_icache_fsm = ICACHE_CC_CLEANUP;
1040                        // }
1041                    }
1042                    break;
1043                }
1044                /////////////////////
1045            case ICACHE_UNC_WAIT:
1046                {
1047                    m_cost_ins_miss_frz++;
1048                    if ( r_tgt_icache_req ) {   // external request
1049                        r_icache_fsm = ICACHE_CC_CHECK;
1050                        r_icache_fsm_save = r_icache_fsm.read();
1051                        break;
1052                    }
1053
1054                    bool ok = CACHE_MISS_BUF_RSP_VAL(i,0);
1055
1056                    if (ok)
1057                    {
1058                        if ( r_vci_rsp_ins_error ) {
1059                            r_icache_fsm = ICACHE_ERROR;
1060                        } else {
1061                            r_icache_fsm = ICACHE_IDLE;
1062                            r_icache_buf_unc_valid = true;
1063                        }
1064                    }
1065                    break;
1066                }
1067                //////////////////
1068            case ICACHE_ERROR:
1069                {
1070                    if ( (addr_40)ireq.addr == (addr_40)r_icache_addr_save ) {
1071                        irsp.error          = true;
1072                        irsp.valid          = true;
1073                    }
1074                    r_icache_fsm = ICACHE_IDLE;
1075                    r_vci_rsp_ins_error = false;
1076                    break;
1077                }
1078                //////////////////////
1079            case ICACHE_MISS_UPDT:
1080                {
1081                    size_t     word = r_icache_update_addr.read();
1082                    vci_addr_t addr = (vci_addr_t) r_icache_addr_save.read();
1083                    size_t     way  = 0;
1084                    size_t     set  = 0;
1085
1086                    // need invalid rsp, don't select a victim
1087                    if (not r_icache_inval_rsp )
1088                    {
1089#if CC_XCACHE_WRAPPER_SELECT_VICTIM
1090                        way = r_icache_miss_way.read();
1091                        set = r_icache_miss_set.read();
1092#else
1093
1094                        // First word : select an victim !
1095                        if (word == 0)
1096                        {
1097                            vci_addr_t victim;
1098                       
1099                            // r_icache_cleanup_req is false because is the transition condition to go in ICACHE_MISS_UPDT state
1100                            r_icache_cleanup_req  = r_icache.victim_select(addr, &victim, &way, &set );
1101                            r_icache.victim_update_tag(addr, way, set);
1102                       
1103                            r_icache_cleanup_line = (addr_40) victim;
1104                            r_icache_miss_way     = way;
1105                            r_icache_miss_set     = set;
1106                        }
1107                        else
1108                        {
1109                            way = r_icache_miss_way.read();
1110                            set = r_icache_miss_set.read();
1111                        }
1112#endif
1113                    }
1114                    bool val = CACHE_MISS_BUF_RSP_VAL(i,word);
1115
1116                    if (val)
1117                    {
1118                        PRINTF("    * <ICACHE> rsp_val            : %d/%d\n",(int)r_icache_update_addr,m_icache_words);
1119                        PRINTF("    * <ICACHE> r_icache_inval_rsp : %d\n",(int)r_icache_inval_rsp);
1120                        PRINTF("    * <ICACHE> ins : %x\n",(int)CACHE_MISS_BUF_RSP_DATA(i,word));
1121
1122                        // m_cpt_icache_dir_write++;
1123                        // m_cpt_icache_data_write++;
1124                        // if ( ireq.valid ) m_cost_ins_miss_frz++;
1125
1126                        // if need invalid rsp, don't modify the cache, but pop the buf_rsp
1127                        if (not r_icache_inval_rsp )
1128                            r_icache.write(way, set, word, CACHE_MISS_BUF_RSP_DATA(i,word));
1129                        CACHE_MISS_BUF_RSP_POP(i);
1130
1131                        r_icache_update_addr = ++word;
1132                           
1133                        // if last word, finish the update
1134                        if (word >= m_icache_words)
1135                        {
1136                            // Last word : if previous invalid_rsp, can cleanup, else update the TAG
1137                            if (r_icache_inval_rsp)
1138                            {
1139                                r_icache_inval_rsp  = false;
1140                                r_icache_fsm = ICACHE_CC_CLEANUP;
1141                            }
1142                            else
1143                            {
1144#if CC_XCACHE_WRAPPER_SELECT_VICTIM
1145                                r_icache.victim_update_tag(addr, way, set);
1146#endif
1147                                r_icache_fsm = ICACHE_IDLE;
1148                            }
1149                        }
1150                    }
1151
1152                    break;
1153                }
1154                ////////////////////
1155            case ICACHE_CC_CLEANUP:
1156                {
1157                    // external cache invalidate request
1158                    if ( r_tgt_icache_req )     
1159                    {
1160                        r_icache_fsm = ICACHE_CC_CHECK;
1161                        r_icache_fsm_save = r_icache_fsm.read();
1162                        break;
1163                    }
1164                    // cleanup
1165                    if(not r_icache_cleanup_req){
1166                        r_icache_cleanup_req = true;
1167                        r_icache_cleanup_line = r_icache_addr_save.read() >> m_icache_words_shift;
1168                        r_icache_fsm = ICACHE_IDLE;
1169                    }
1170                    break;
1171                }
1172                /////////////////////
1173            case ICACHE_CC_CHECK:   // read directory in case of invalidate or update request
1174                {
1175
1176                    m_cpt_icache_dir_read  += m_icache_ways;
1177                    m_cpt_icache_data_read += m_icache_ways;
1178                    addr_40 ad = r_tgt_addr;
1179                    data_t  icache_rdata = 0;
1180
1181                    if((r_icache_fsm_save == ICACHE_MISS_WAIT) and
1182                            ( (r_icache_addr_save.read() & ~((m_icache_words<<2)-1)) == (ad & ~((m_icache_words<<2)-1)))) {
1183                        r_icache_inval_rsp = true;
1184                        r_tgt_icache_req = false;
1185                        if(r_tgt_update){    // Also send a cleanup and answer
1186                            r_tgt_icache_rsp     = true;
1187                        } else {            // Also send a cleanup but don't answer
1188                            r_tgt_icache_rsp     = false;
1189                        }
1190                        r_icache_fsm = r_icache_fsm_save;
1191                    } else {
1192                        bool    icache_hit   = r_icache.read(ad, &icache_rdata);
1193                        if ( icache_hit and r_tgt_update )
1194                        {
1195#if CC_XCACHE_WRAPPER_CC_UPDATE_MULTI_CYCLE
1196                            uint32_t word  = r_cache_word;
1197                            data_t   mask  = vci_param::be2mask(r_tgt_be[word]);
1198                            data_t   rdata = 0;
1199
1200                            r_icache.read(ad+word*4,&rdata);
1201                            r_tgt_buf[word] = (mask & r_tgt_buf[word]) | (~mask & rdata);
1202                           
1203                            word ++;
1204#if CC_XCACHE_WRAPPER_CC_UPDATE_MULTI_CYCLE_OPT
1205                            for (; word<m_icache_words; ++word)
1206                                if (r_tgt_be[word] != 0)
1207                                    break;
1208#endif
1209
1210                            if (word==m_icache_words)
1211                            {
1212                                r_icache_fsm = ICACHE_CC_UPDT;
1213
1214#if CC_XCACHE_WRAPPER_CC_UPDATE_MULTI_CYCLE_OPT
1215                                for (word=0; word<m_icache_words; ++word)
1216                                    if (r_tgt_be[word] != 0)
1217                                        break;
1218#else
1219                                word = 0;
1220#endif
1221                            }
1222                            r_cache_word = word;
1223#else //CC_XCACHE_WRAPPER_CC_UPDATE_MULTI_CYCLE
1224                            r_icache_fsm = ICACHE_CC_UPDT;
1225                            // complete the line buffer in case of update
1226                            for(size_t i=0; i<m_icache_words; i++){
1227                                data_t rdata = 0;
1228                                r_icache.read(ad + i*4,&rdata);
1229                                data_t mask = vci_param::be2mask(r_tgt_be[i]);
1230                                r_tgt_buf[i] = (mask & r_tgt_buf[i]) | (~mask & rdata);
1231                            }
1232#endif //CC_XCACHE_WRAPPER_CC_UPDATE_MULTI_CYCLE
1233                        } else if ( icache_hit and not r_tgt_update ) {
1234                            r_icache_fsm = ICACHE_CC_INVAL;
1235                        } else { // instruction not found (can happen)
1236                            r_tgt_icache_req = false;
1237                            if(r_tgt_update){
1238                                r_tgt_icache_rsp = true;
1239                            } else {
1240                                r_tgt_icache_rsp = false;
1241                            }
1242                            r_icache_fsm = r_icache_fsm_save;
1243                        }
1244                    }
1245                    break;
1246                }
1247                /////////////////////
1248            case ICACHE_CC_INVAL: 
1249                {                       
1250                    addr_40    ad  = r_tgt_addr;
1251                    if ( ireq.valid ) m_cost_ins_miss_frz++;
1252                    m_cpt_icache_dir_read += m_icache_ways;
1253                    r_tgt_icache_rsp = true;
1254                    r_icache.inval(ad);
1255                    r_tgt_icache_req = false;
1256                    r_icache_fsm = r_icache_fsm_save;
1257                    break;
1258                }   
1259                /////////////////////
1260            case ICACHE_CC_UPDT:
1261                {                       
1262                    addr_40 ad = r_tgt_addr.read();
1263                    m_cpt_icache_dir_write++;
1264                    m_cpt_icache_data_write++;
1265
1266#if CC_XCACHE_WRAPPER_CC_UPDATE_MULTI_CYCLE
1267                    uint32_t word  = r_cache_word;
1268
1269                    if(r_tgt_be[word])
1270                        r_icache.write(ad+word*4, r_tgt_buf[word]);
1271
1272                    word ++;
1273#if CC_XCACHE_WRAPPER_CC_UPDATE_MULTI_CYCLE_OPT
1274                    for (; word<m_icache_words; ++word)
1275                        if (r_tgt_be[word] != 0)
1276                            break;
1277#endif
1278
1279                    if (word==m_icache_words)
1280                    {
1281                        r_tgt_icache_req = false;
1282                        r_tgt_icache_rsp = true;
1283                        r_icache_fsm     = r_icache_fsm_save.read();
1284                        word = 0;
1285                    }
1286                    r_cache_word = word;
1287#else //CC_XCACHE_WRAPPER_CC_UPDATE_MULTI_CYCLE
1288                    data_t* buf    = r_tgt_buf;
1289                    for(size_t i=0; i<m_icache_words;i++){
1290                        if(r_tgt_be[i]) r_icache.write( ad + i*4, buf[i]);
1291                    }
1292                    r_tgt_icache_req = false;
1293                    r_tgt_icache_rsp = true;
1294                    r_icache_fsm     = r_icache_fsm_save.read();
1295#endif //CC_XCACHE_WRAPPER_CC_UPDATE_MULTI_CYCLE
1296
1297                    break;
1298                }   
1299
1300        } // end switch r_icache_fsm
1301
1302#if CC_XCACHE_WRAPPER_DEBUG
1303        if (m_cpt_total_cycles>=CC_XCACHE_WRAPPER_DEBUG_CYCLE_MIN)
1304            std::cout << "    * Instruction Response : " << irsp << std::endl;
1305#endif
1306
1307        //////////////////////////////////////////////////////////////////////://///////////
1308        // The DCACHE FSM controls the following ressources:
1309        // - r_dcache_fsm
1310        // - r_dcache_fsm_save
1311        // - r_dcache (data cache access)
1312        // - r_dcache_addr_save
1313        // - r_dcache_wdata_save
1314        // - r_dcache_rdata_save
1315        // - r_dcache_type_save
1316        // - r_dcache_be_save
1317        // - r_dcache_cached_save
1318        // - r_dcache_miss_req set
1319        // - r_dcache_unc_req set
1320        // - r_dcache_cleanup_req set
1321        // - r_vci_rsp_data_error reset
1322        // - r_tgt_dcache_req reset
1323        // - r_wbuf write
1324        // - dreq & drsp structures for communication with the processor
1325        //
1326        // 1/ EXTERNAL REQUEST :
1327        //    There is an external request when the tgt_dcache req flip-flop is set,
1328        //    requesting a line invalidation or a line update.
1329        //    External requests are taken into account in the states  IDLE, WRITE_REQ, 
1330        //    UNC_WAIT, MISS_WAIT, and have the highest priority :
1331        //    The actions associated to the pre-empted state are not executed, the DCACHE FSM
1332        //    goes to the CC_CHECK state to execute the requested action, and returns to the
1333        //    pre-empted state.
1334        //  2/ PROCESSOR REQUEST :
1335        //   In order to support VCI write burst, the processor requests are taken into account
1336        //   in the WRITE_REQ state as well as in the IDLE state.
1337        //   - In the IDLE state, the processor request cannot be satisfied if
1338        //   there is a cached read miss, or an uncached read.
1339        //   - In the WRITE_REQ state, the request cannot be satisfied if
1340        //   there is a cached read miss, or an uncached read,
1341        //   or when the write buffer is full.
1342        //   - In all other states, the processor request is not satisfied.
1343        //
1344        //   The cache access takes into account the cacheability_table.
1345        //   In case of processor request, there is five conditions to exit the IDLE state:
1346        //   - CACHED READ MISS => to the MISS_WAIT state (waiting the r_miss_ok signal),
1347        //     then to the MISS_UPDT state, and finally to the IDLE state.
1348        //   - UNCACHED READ  => to the UNC_WAIT state (waiting the r_miss_ok signal),
1349        //     and to the IDLE state.
1350        //   - CACHE INVALIDATE HIT => to the INVAL state for one cycle, then to IDLE state.
1351        //   - WRITE MISS => directly to the WRITE_REQ state to access the write buffer.
1352        //   - WRITE HIT => to the WRITE_UPDT state, then to the WRITE_REQ state.
1353        //
1354        // Error handling :  Read Bus Errors are synchronous events, but
1355        // Write Bus Errors are asynchronous events (processor is not frozen).
1356        // - If a Read Bus Error is detected, the VCI_RSP FSM sets the
1357        //   r_vci_rsp_data_error flip-flop, and the synchronous error is signaled
1358        //   by the DCACHE FSM.
1359        // - If a Write Bus Error is detected, the VCI_RSP FSM  signals
1360        //   the asynchronous error using the setWriteBerr() method.
1361        ///////////////////////////////////////////////////////////////////////////////////
1362
1363#if CC_XCACHE_WRAPPER_DEBUG
1364        if (m_cpt_total_cycles>=CC_XCACHE_WRAPPER_DEBUG_CYCLE_MIN)
1365            std::cout << "    * Data        Request  : " << dreq << std::endl;
1366#endif
1367
1368        switch ( r_dcache_fsm ) {
1369
1370                /////////////////
1371            case DCACHE_IDLE:
1372                {
1373                    if ( r_tgt_dcache_req ) {   // external request
1374                        r_dcache_fsm = DCACHE_CC_CHECK;
1375                        r_dcache_fsm_save = r_dcache_fsm;
1376                        break;
1377                    }
1378
1379                    if ( dreq.valid ) {
1380                        PRINTF("    * <DCACHE> Have dreq\n");
1381
1382                        data_t      dcache_rdata       = 0;
1383                        // dcache_cached and dcache_hit don't used with dreq.type == {DATA_SC, XTN_READ, XTN_WRITE}
1384                        bool        dcache_cached      = m_cacheability_table[(vci_addr_t)dreq.addr];
1385                        bool        dcache_hit         = r_dcache.read((vci_addr_t) dreq.addr, &dcache_rdata);
1386                        bool        dcache_cleanup_hit = r_dcache_cleanup_req and (((addr_40)dreq.addr >> (addr_40)m_dcache_words_shift) == r_dcache_cleanup_line.read());
1387
1388                        PRINTF("    * <DCACHE> hit %d - cached %d - cleanup_hit %d\n",dcache_hit, dcache_cached, dcache_cleanup_hit);
1389                       
1390                        m_cpt_dcache_data_read += m_dcache_ways;
1391                        m_cpt_dcache_dir_read  += m_dcache_ways;
1392
1393                        switch( dreq.type ) {
1394                            case iss_t::DATA_READ:
1395                            case iss_t::DATA_LL:
1396                                {
1397                                    m_cpt_data_read++; // new dcache read
1398
1399                                    if (dcache_hit) // no special test for uncached read, because it's always miss
1400                                        {
1401                                            // address is in the cache : return the word
1402                                            r_dcache_fsm = DCACHE_IDLE;
1403                                            drsp.valid   = true;
1404                                            drsp.rdata   = dcache_rdata; // return read data (cf dcache_hit)
1405                                           
1406                                            // if the request is a Load Linked instruction, save request information
1407                                            if(dreq.type == iss_t::DATA_LL)
1408                                                {
1409                                                    PRINTF("    * <DCACHE> ll_valid = true\n");
1410
1411                                                    r_dcache_ll_valid = true;
1412                                                    r_dcache_ll_data = dcache_rdata;
1413                                                    r_dcache_ll_addr = (vci_addr_t) dreq.addr;
1414#ifdef COHERENCE_DEBUG
1415                                                    std::cout << "Value returned for LL at address : " << std::hex << dreq.addr << " data : " << std::dec << dcache_rdata<< std::endl;
1416                                                    r_dcache.read((vci_addr_t) dreq.addr, &dcache_rdata);
1417                                                    std::cout << "Value stored at this  address : " << std::hex << dreq.addr << " data : " << std::dec << dcache_rdata<< std::endl;
1418#endif
1419                                                }
1420                                        }
1421                                    else
1422                                        {
1423                                            if (not dcache_cleanup_hit)
1424                                            {
1425                                                CACHE_MISS_BUF_REQ_INIT(d);
1426                                               
1427                                                // Miss : send signal at the CMD_FSM (via r_dcache_miss_req or r_dcache_unc_req)
1428                                                if ( dcache_cached ) {
1429                                                    m_cpt_data_read_miss++;
1430                                                    m_cost_data_miss_frz++;
1431                                                    r_dcache_miss_req = true;
1432#if CC_XCACHE_WRAPPER_SELECT_VICTIM
1433                                                    r_dcache_fsm = DCACHE_MISS_VICTIM;
1434#else
1435                                                    r_dcache_fsm = DCACHE_MISS_WAIT;
1436#endif
1437                                                   
1438                                                } else {
1439                                                    if (not r_dcache_previous_unc.read()) // strongly order to the uncached access
1440                                                    {
1441                                                        r_dcache_previous_unc = true;
1442                                                       
1443                                                        m_cpt_data_read_uncached++;
1444                                                        m_cost_unc_read_frz++;
1445                                                        r_dcache_unc_req = true;
1446                                                        r_dcache_fsm = DCACHE_UNC_WAIT;
1447                                                    }
1448                                                }
1449                                            }
1450                                        }
1451                                }
1452                                break;
1453                            case iss_t::DATA_SC:
1454                            {
1455                                PRINTF("    * <DCACHE> DATA_SC - ll_valid = %d\n",r_dcache_ll_valid.read());
1456
1457                                if (not r_dcache_previous_unc.read() and not dcache_cleanup_hit) // strongly order to the uncached access
1458                                {
1459                                    //m_cpt_data_read_unc++; // instruction must read the memory in uncached mode
1460                                    m_cost_unc_read_frz++;
1461                                   
1462                                    // if previous load linked (with the same address), make a transaction
1463                                    // else, keep in IDLE state and return 1 (no OK)
1464                                    if(r_dcache_ll_valid.read() and (r_dcache_ll_addr.read() == (vci_addr_t)dreq.addr)){
1465                                        PRINTF("    * <DCACHE> have previous load linked\n");
1466                                       
1467                                        r_dcache_previous_unc = true;
1468
1469                                        r_dcache_sc_req   = true;
1470
1471                                        CACHE_MISS_BUF_REQ_INIT(d);
1472
1473                                        r_dcache_fsm = DCACHE_SC_WAIT;
1474                                    } else {
1475                                        PRINTF("    * <DCACHE> don't have previous load linked\n");
1476                                       
1477                                        drsp.valid = true;
1478                                        drsp.rdata = 1; // SC rsp NOK
1479                                        r_dcache_ll_valid = false;
1480                                    }
1481                                }
1482
1483                                break;
1484                            }
1485                            case iss_t::XTN_READ:
1486                            case iss_t::XTN_WRITE:
1487                                {
1488                                    bool drsp_valid = false;
1489                                    // only DCACHE INVALIDATE and SYNC request are supported
1490                                    switch (dreq.addr>>2)
1491                                        {
1492                                        case iss_t::XTN_DCACHE_INVAL :
1493                                            {
1494                                                drsp_valid = true;
1495                                                r_dcache_fsm = DCACHE_INVAL;
1496                                                break;
1497                                            }
1498                                        case iss_t::XTN_SYNC :
1499                                            {
1500                                                // Test if write buffer is already empty
1501                                                //  * gain : 1 cycle
1502                                                //  * cost : can be on the critical path
1503                                                if (r_wbuf.empty())
1504                                                    {
1505                                                        drsp_valid = true;
1506                                                        r_dcache_fsm = DCACHE_IDLE;
1507                                                    }
1508                                                else
1509                                                    {
1510                                                        drsp_valid = false;
1511                                                        r_dcache_fsm = DCACHE_SYNC;
1512                                                    }
1513                                                break;
1514                                            }
1515                                        default :
1516                                            {
1517                                                // std::cout << "Warning in VCI_CC_XCACHE_WRAPPER " << name() << std::endl;
1518                                                // std::cout << "Unsupported  external access : " << (dreq.addr>>2) << std::endl;
1519
1520                                                r_dcache_fsm = DCACHE_IDLE;
1521                                            }
1522                                        }//end switch (dreq.addr>>2)
1523
1524                                    drsp.valid = drsp_valid;
1525                                    drsp.rdata = 0;
1526                                    break;
1527                                }
1528                            case iss_t::DATA_WRITE:
1529
1530                                if (dcache_cached or not r_dcache_previous_unc.read()) // strongly order to the uncached access
1531                                {
1532                                    bool drsp_valid;
1533
1534                                    drsp_valid = r_wbuf.write((addr_40) dreq.addr, dreq.be, dreq.wdata, dcache_cached);
1535
1536                                    if (drsp_valid)
1537                                    {
1538                                        m_cpt_data_write++;
1539                                       
1540                                        if (not dcache_cached)
1541                                        {
1542                                            r_dcache_previous_unc = true;
1543                                            m_cpt_data_write_uncached++;
1544                                        }
1545                                        else if (not dcache_hit)
1546                                            m_cpt_data_write_miss++;
1547                                       
1548                                        if ( dcache_hit) {
1549                                            r_dcache_fsm = DCACHE_WRITE_UPDT;
1550                                        } else {
1551                                            r_dcache_fsm = DCACHE_IDLE;
1552                                        }
1553                                    }
1554
1555                                    drsp.valid = drsp_valid;
1556                                    drsp.rdata = 0;
1557                                }
1558                                break;
1559                        } // end switch dreq.type
1560
1561                        r_dcache_addr_save      = (addr_40) dreq.addr;
1562                        r_dcache_type_save      = dreq.type;
1563                        r_dcache_wdata_save     = dreq.wdata;
1564                        r_dcache_be_save        = dreq.be;
1565                        r_dcache_rdata_save     = dcache_rdata;
1566                        r_dcache_cached_save    = dcache_cached;
1567                       
1568                    } else {    // end if dreq.valid
1569                        r_dcache_fsm = DCACHE_IDLE;
1570                    }
1571                   
1572                    break;
1573                }
1574                ///////////////////////
1575            case DCACHE_WRITE_UPDT:
1576                {
1577                    m_cpt_dcache_data_write++;
1578                    data_t mask = vci_param::be2mask(r_dcache_be_save);
1579                    data_t wdata = (mask & r_dcache_wdata_save) | (~mask & r_dcache_rdata_save);
1580                    vci_addr_t ad = r_dcache_addr_save.read();
1581                    r_dcache.write(ad, wdata);
1582
1583                    r_dcache_fsm = DCACHE_IDLE;
1584
1585                    break;
1586                }
1587                //////////////////////
1588#if CC_XCACHE_WRAPPER_SELECT_VICTIM
1589            case DCACHE_MISS_VICTIM:
1590                {
1591                    if (not r_dcache_cleanup_req.read())
1592                     {
1593                         size_t     way;
1594                         size_t     set;
1595                         vci_addr_t addr = (vci_addr_t) r_dcache_addr_save.read();
1596                         vci_addr_t victim;
1597                         
1598                         r_dcache_cleanup_req  = r_dcache.victim_select(addr, &victim, &way, &set );
1599                         r_dcache_cleanup_line = (addr_40) victim;
1600                         r_dcache_miss_way     = way;
1601                         r_dcache_miss_set     = set;
1602                         
1603                         r_dcache_fsm = DCACHE_MISS_WAIT;
1604                     }
1605                   
1606                    break;
1607                }
1608#endif
1609                //////////////////////
1610            case DCACHE_MISS_WAIT:
1611                {
1612
1613                    if ( dreq.valid ) m_cost_data_miss_frz++;
1614                    if ( r_tgt_dcache_req.read() ) {   // external request
1615                        r_dcache_fsm = DCACHE_CC_CHECK;
1616                        r_dcache_fsm_save = r_dcache_fsm;
1617                        break;
1618                    }
1619
1620                    bool val = CACHE_MISS_BUF_RSP_VAL(d,0);
1621                    if (val)
1622                    {
1623                        // if (not r_dcache_inval_rsp )
1624                        //  {
1625
1626                        // Miss read response and no invalidation
1627                        if ( r_vci_rsp_data_error )
1628                        {
1629                            r_dcache_fsm = DCACHE_ERROR;
1630                        }
1631                        else
1632                        {
1633#if not CC_XCACHE_WRAPPER_SELECT_VICTIM
1634                            if (not r_dcache_cleanup_req.read())
1635#endif
1636                            {
1637                                r_dcache_update_addr = 0;
1638                                r_dcache_fsm         = DCACHE_MISS_UPDT;
1639                            }
1640                        }
1641                        //  }
1642                        // else
1643                        // {
1644                        //     r_dcache_inval_rsp  = false;
1645
1646                        //     // Miss read response and invalidation
1647                        //     if ( r_vci_rsp_data_error ) {
1648                        //         r_dcache_fsm = DCACHE_ERROR;
1649                        //     } else {
1650                        //         r_dcache_fsm = DCACHE_CC_CLEANUP;
1651                        //     }
1652                        // }
1653                    }
1654                    break;
1655                }
1656                //////////////////////
1657            case DCACHE_MISS_UPDT:
1658                {
1659                    size_t     word = r_dcache_update_addr.read();
1660                    vci_addr_t addr = (vci_addr_t) r_dcache_addr_save.read();
1661                    size_t     way  = 0;
1662                    size_t     set  = 0;
1663                   
1664                    // need invalid rsp, don't select a victim
1665                    if (not r_dcache_inval_rsp )
1666                    {
1667#if CC_XCACHE_WRAPPER_SELECT_VICTIM
1668                        way = r_dcache_miss_way.read();
1669                        set = r_dcache_miss_set.read();
1670#else
1671                        // First word : select an victim !
1672                        if (word == 0)
1673                        {
1674                            vci_addr_t victim;
1675                       
1676                            // r_dcache_cleanup_req is false (condition to enter in DCACHE_MISS_UPDT
1677                            r_dcache_cleanup_req  = r_dcache.victim_select(addr, &victim, &way, &set );
1678                            r_dcache.victim_update_tag(addr, way, set);
1679                            r_dcache_cleanup_line = (addr_40) victim;
1680
1681                            r_dcache_miss_way     = way;
1682                            r_dcache_miss_set     = set;
1683                        }
1684                        else
1685                        {
1686                            way = r_dcache_miss_way.read();
1687                            set = r_dcache_miss_set.read();
1688                        }
1689#endif
1690                    }
1691
1692                    bool val = CACHE_MISS_BUF_RSP_VAL(d,word);
1693                    if (val)
1694                    {
1695                        // m_cpt_dcache_dir_write++;
1696                        // if ( ireq.valid ) m_cost_data_miss_frz++;
1697
1698                        // if need invalid rsp, don't modify the cache, but pop the buf_rsp
1699                        if (not r_dcache_inval_rsp )
1700                        {
1701                            r_dcache.write(way, set, word, CACHE_MISS_BUF_RSP_DATA(d,word));
1702                            m_cpt_dcache_data_write++;
1703                        }
1704
1705                        CACHE_MISS_BUF_RSP_POP(d);
1706                        r_dcache_update_addr = ++word;
1707                           
1708                        // if last word, finish the update
1709                        if (word >= m_dcache_words)
1710                        {
1711                            // Last word : if previous invalid_rsp, can cleanup, else update the TAG
1712                            if (r_dcache_inval_rsp)
1713                            {
1714                                r_dcache_inval_rsp  = false;
1715                                r_dcache_fsm = DCACHE_CC_CLEANUP;
1716                            }
1717                            else
1718                            {
1719#if CC_XCACHE_WRAPPER_SELECT_VICTIM
1720                                r_dcache.victim_update_tag(addr, way, set);
1721#endif
1722                                r_dcache_fsm = DCACHE_IDLE;
1723                            }
1724                        }
1725                    }
1726               
1727                    break;
1728                }
1729                ////////////////////
1730            case DCACHE_UNC_WAIT:
1731                {
1732                    if ( dreq.valid ) m_cost_unc_read_frz++;
1733                    if ( r_tgt_dcache_req ) {   // external request
1734                        r_dcache_fsm = DCACHE_CC_CHECK;
1735                        r_dcache_fsm_save = r_dcache_fsm;
1736                        break;
1737                    }
1738
1739                    bool ok = CACHE_MISS_BUF_RSP_VAL(d,0);
1740
1741                    if (ok) {
1742                        if ( r_vci_rsp_data_error ) {
1743                            r_dcache_fsm = DCACHE_ERROR;
1744                        } else {
1745                            data_t rdata = CACHE_MISS_BUF_RSP_DATA(d,0);
1746                            CACHE_MISS_BUF_RSP_POP(d);
1747
1748                            if(dreq.type == iss_t::DATA_LL){
1749                                PRINTF("    * <DCACHE> ll_valid = true\n");
1750
1751                                r_dcache_ll_valid = true;
1752                                r_dcache_ll_data = rdata;
1753                                r_dcache_ll_addr = (vci_addr_t) dreq.addr;
1754                            }
1755                            r_dcache_fsm = DCACHE_IDLE;
1756                            drsp.valid = true;
1757                            drsp.rdata = rdata;
1758                        }
1759                    }
1760                    break;
1761                }
1762                ////////////////////
1763            case DCACHE_SC_WAIT:
1764                {
1765                    if ( dreq.valid ) m_cost_unc_read_frz++;
1766                    if ( r_tgt_dcache_req ) {   // external request
1767                        r_dcache_fsm = DCACHE_CC_CHECK;
1768                        r_dcache_fsm_save = r_dcache_fsm;
1769                        break;
1770                    }
1771
1772                    bool ok = CACHE_MISS_BUF_RSP_VAL(d,0);
1773
1774                    if (ok) {
1775                        if ( r_vci_rsp_data_error ) {
1776                            r_dcache_fsm = DCACHE_ERROR;
1777                        } else {
1778                            r_dcache_fsm = DCACHE_IDLE;
1779                            drsp.valid = true;
1780                            drsp.rdata = CACHE_MISS_BUF_RSP_DATA(d,0);
1781                            CACHE_MISS_BUF_RSP_POP(d);
1782                            r_dcache_ll_valid = false;
1783                        }
1784                    }
1785                    break;
1786                }
1787
1788                //////////////////
1789            case DCACHE_ERROR:
1790                {
1791                    r_dcache_fsm = DCACHE_IDLE;
1792                    r_vci_rsp_data_error = false;
1793                    drsp.error = true;
1794                    drsp.valid = true;
1795                    break;
1796                }
1797                /////////////////   
1798            case DCACHE_INVAL:
1799                {
1800                    if ( r_tgt_dcache_req.read() ) {   // external request
1801                        r_dcache_fsm = DCACHE_CC_CHECK;
1802                        r_dcache_fsm_save = r_dcache_fsm;
1803                        break;
1804                    }
1805                    if( not r_dcache_cleanup_req.read() ){
1806                        m_cpt_dcache_dir_read += m_dcache_ways;
1807                        vci_addr_t  ad  = r_dcache_addr_save.read();
1808                        r_dcache_cleanup_req = r_dcache.inval(ad);
1809                        r_dcache_cleanup_line = r_dcache_addr_save.read() >> m_dcache_words_shift;
1810
1811                        r_dcache_fsm = DCACHE_IDLE;
1812                    }
1813                    break;
1814                }
1815            case DCACHE_SYNC :
1816                {
1817                    if ( r_tgt_dcache_req ) {   // external request
1818                        r_dcache_fsm = DCACHE_CC_CHECK;
1819                        r_dcache_fsm_save = r_dcache_fsm;
1820                        break;
1821                    }
1822
1823                    if (r_wbuf.empty())
1824                        {
1825                            drsp.valid = true; // end, can accept the sync request
1826                            r_dcache_fsm = DCACHE_IDLE;
1827                        }
1828                    break;
1829                }
1830                /////////////////////
1831            case DCACHE_CC_CHECK:   // read directory in case of invalidate or update request
1832                {
1833                    addr_40  ad          = r_tgt_addr;
1834                    data_t  dcache_rdata = 0;
1835
1836                    if((r_dcache_fsm_save == DCACHE_MISS_WAIT) and
1837                            ( (r_dcache_addr_save.read() & ~((m_dcache_words<<2)-1)) == (ad & ~((m_dcache_words<<2)-1)))) {
1838                        r_dcache_inval_rsp = true;
1839                        r_tgt_dcache_req = false;
1840                        if(r_tgt_update){    // Also send a cleanup and answer
1841                            r_tgt_dcache_rsp     = true;
1842                        } else {            // Also send a cleanup but don't answer
1843                            r_tgt_dcache_rsp     = false;
1844                        }
1845                        r_dcache_fsm = r_dcache_fsm_save;
1846                    } else {
1847                        bool    dcache_hit   = r_dcache.read(ad, &dcache_rdata);
1848
1849                        m_cpt_dcache_data_read += m_dcache_ways;
1850                        m_cpt_dcache_dir_read += m_dcache_ways;
1851
1852#ifdef COHERENCE_DEBUG
1853                        std::cout << "PROC " << m_srcid_rw << " DCACHE_CC_CHECK, hit ? : " << dcache_hit << std::endl;
1854#endif
1855                        if ( dcache_hit and r_tgt_update )
1856                        {
1857#if CC_XCACHE_WRAPPER_CC_UPDATE_MULTI_CYCLE
1858                            uint32_t word  = r_cache_word;
1859                            data_t   mask  = vci_param::be2mask(r_tgt_be[word]);
1860                            data_t   rdata = 0;
1861
1862                            r_dcache.read(ad+word*4,&rdata);
1863                           
1864                            r_tgt_buf[word] = (mask & r_tgt_buf[word]) | (~mask & rdata);
1865
1866                            word ++;
1867#if CC_XCACHE_WRAPPER_CC_UPDATE_MULTI_CYCLE_OPT
1868                            for (; word<m_dcache_words; ++word)
1869                                if (r_tgt_be[word] != 0)
1870                                    break;
1871#endif
1872
1873                            if (word==m_dcache_words)
1874                            {
1875                                r_dcache_fsm = DCACHE_CC_UPDT;
1876#if CC_XCACHE_WRAPPER_CC_UPDATE_MULTI_CYCLE_OPT
1877                                for (word=0; word<m_dcache_words; ++word)
1878                                    if (r_tgt_be[word] != 0)
1879                                        break;
1880#else
1881                                word = 0;
1882#endif
1883                            }
1884                            r_cache_word = word;
1885#else //CC_XCACHE_WRAPPER_CC_UPDATE_MULTI_CYCLE
1886                            // complete the line buffer in case of update
1887                            for(size_t i=0; i<m_dcache_words; i++){
1888                                data_t rdata = 0;
1889                                r_dcache.read(ad + i*4,&rdata);
1890                                data_t mask = vci_param::be2mask(r_tgt_be[i]);
1891                                r_tgt_buf[i] = (mask & r_tgt_buf[i]) | (~mask & rdata);
1892                            }
1893                            r_dcache_fsm = DCACHE_CC_UPDT;
1894#endif //CC_XCACHE_WRAPPER_CC_UPDATE_MULTI_CYCLE
1895                        } else if ( dcache_hit and not r_tgt_update ) {
1896                            r_dcache_fsm = DCACHE_CC_INVAL;
1897                        } else {
1898                            if(r_tgt_update){
1899                                r_tgt_dcache_rsp = true;
1900                            } else {
1901                                r_tgt_dcache_rsp = false;
1902                            }
1903                            r_tgt_dcache_req = false;
1904                            r_dcache_fsm = r_dcache_fsm_save;
1905                        }
1906                    }
1907                    break;
1908                }
1909                ///////////////////
1910            case DCACHE_CC_UPDT:    // update directory and data cache       
1911                {
1912                    addr_40 ad = r_tgt_addr;
1913
1914                    m_cpt_dcache_dir_write++;
1915                    m_cpt_dcache_data_write++;
1916
1917# ifdef COHERENCE_DEBUG
1918                    std::cout << "PROC " << m_srcid_rw << " DCACHE_CC_UPDT, update : " << std::endl;
1919# endif
1920
1921#if CC_XCACHE_WRAPPER_CC_UPDATE_MULTI_CYCLE
1922                    uint32_t word  = r_cache_word;
1923                   
1924                    if(r_tgt_be[word])
1925                        r_dcache.write(ad+word*4, r_tgt_buf[word]);
1926# ifdef COHERENCE_DEBUG
1927                    std::cout << " address " << std::hex << ad+word*4 << " data " << std::dec << r_tgt_buf[word] << std::endl;
1928                    data_t rdata = 0xAAAAAAAA;
1929                    r_dcache.read(ad+word*4,&rdata);
1930                    std::cout << "data written " << rdata << std::endl;
1931# endif
1932
1933                    word ++;
1934#if CC_XCACHE_WRAPPER_CC_UPDATE_MULTI_CYCLE_OPT
1935                    for (; word<m_dcache_words; ++word)
1936                        if (r_tgt_be[word] != 0)
1937                            break;
1938#endif
1939                   
1940                    if (word==m_dcache_words)
1941                    {
1942                        r_tgt_dcache_req = false;
1943                        r_tgt_dcache_rsp = true;
1944                        r_dcache_fsm = r_dcache_fsm_save;
1945                        word = 0;
1946                    }
1947                    r_cache_word = word;
1948#else //CC_XCACHE_WRAPPER_CC_UPDATE_MULTI_CYCLE
1949                    data_t* buf = r_tgt_buf;
1950                    for(size_t i=0; i<m_dcache_words; i++){
1951                        if(r_tgt_be[i]) {
1952                            r_dcache.write( ad + i*4, buf[i]);
1953# ifdef COHERENCE_DEBUG
1954                            std::cout << " address " << std::hex << ad+i*4 << " data " << std::dec << buf[i] << std::endl;
1955                            data_t rdata = 0xAAAAAAAA;
1956                            r_dcache.read(ad + i*4,&rdata);
1957                            std::cout << "data written " << rdata << std::endl;
1958# endif //CC_XCACHE_WRAPPER_CC_UPDATE_MULTI_CYCLE
1959                        }
1960                    }
1961                    r_tgt_dcache_req = false;
1962                    r_tgt_dcache_rsp = true;
1963                    r_dcache_fsm = r_dcache_fsm_save;
1964#endif
1965                    break;
1966                }
1967                /////////////////////
1968            case DCACHE_CC_INVAL:   // invalidate a cache line
1969                {
1970                    addr_40  ad      = r_tgt_addr;
1971                    r_tgt_dcache_rsp = true;
1972                    r_dcache.inval(ad);
1973                    r_tgt_dcache_req = false;
1974                    r_dcache_fsm = r_dcache_fsm_save;
1975                    break;
1976                }
1977                ///////////////////
1978            case DCACHE_CC_CLEANUP:   
1979                {
1980                    // external cache invalidate request
1981                    if ( r_tgt_dcache_req )   
1982                    {
1983                        r_dcache_fsm = DCACHE_CC_CHECK;
1984                        r_dcache_fsm_save = r_dcache_fsm;
1985                        break;
1986                    }       
1987                    // cleanup
1988                    if(not r_dcache_cleanup_req){
1989                        r_dcache_cleanup_req = true;
1990                        r_dcache_cleanup_line = r_dcache_addr_save.read() >> m_dcache_words_shift;
1991                        r_dcache_fsm = DCACHE_IDLE;
1992                    }
1993                    break;
1994                }   
1995
1996        } // end switch r_dcache_fsm
1997       
1998        ////////// write buffer state update  /////////////
1999        // The update() method must be called at each cycle to update the internal state.
2000        // All pending write requests must be locked in case of SYNC
2001        bool wbuf_flush=(r_dcache_fsm == DCACHE_SYNC);
2002#if   (CC_XCACHE_WRAPPER_WBUF_UPDATE_SCHEME==1)
2003        r_wbuf.update_multi_scan      (wbuf_flush);
2004#elif (CC_XCACHE_WRAPPER_WBUF_UPDATE_SCHEME==2)
2005        r_wbuf.update_round_robin_scan(wbuf_flush);
2006#elif (CC_XCACHE_WRAPPER_WBUF_UPDATE_SCHEME==3)
2007        r_wbuf.update_one_scan        (wbuf_flush);
2008#else
2009        r_wbuf.update                 (wbuf_flush);
2010#endif
2011
2012#if CC_XCACHE_WRAPPER_DEBUG
2013        if (m_cpt_total_cycles>=CC_XCACHE_WRAPPER_DEBUG_CYCLE_MIN)
2014            std::cout << "    * Data        Response : " << drsp << std::endl;
2015#endif
2016
2017        /////////// execute one iss cycle /////////////////////////////////////////////
2018        {
2019            uint32_t it = 0;
2020            for (size_t i=0; i<(size_t)iss_t::n_irq; i++)
2021                if(p_irq[i].read()) it |= (1<<i);
2022            m_iss.executeNCycles(1, irsp, drsp, it);
2023        }
2024
2025        if ( (ireq.valid and not irsp.valid) or
2026             (dreq.valid and not drsp.valid))
2027        {
2028            m_cpt_frz_cycles++;
2029#if CC_XCACHE_WRAPPER_STOP_SIMULATION
2030            m_stop_simulation_nb_frz_cycles ++;
2031           
2032            if (m_stop_simulation and (m_stop_simulation_nb_frz_cycles >= m_stop_simulation_nb_frz_cycles_max))
2033            {
2034                std::cout << std::dec << "CC_XCACHE_WRAPPER \"" << name() << "\" : cycle " << m_cpt_total_cycles << ", the cpu is frozen since " << m_stop_simulation_nb_frz_cycles << " cycles." << std::endl;
2035                ASSERT(false,"CPU : anormal activity"); // exit
2036            }
2037        }
2038        else
2039        {
2040            m_stop_simulation_nb_frz_cycles = 0; // reinit counter
2041#endif //CC_XCACHE_WRAPPER_STOP_SIMULATION
2042        }
2043
2044
2045#if CC_XCACHE_WRAPPER_DEBUG_DCACHE_TRANSACTION
2046        if (dreq.valid and drsp.valid)
2047        {
2048            log_dcache_transaction_file
2049                << "[" << m_cpt_total_cycles << "]"
2050                << std::hex
2051                << " @ "     << std::setw(8) << (uint32_t)dreq.addr
2052                << " be "    << std::setw(1) << (uint32_t)dreq.be
2053                << " W "     << std::setw(8) << (uint32_t)dreq.wdata
2054                << " R "     << std::setw(8) << (uint32_t)drsp.rdata
2055                << " error "            << (uint32_t)drsp.error
2056                << std::dec
2057                << " "  << type_str(dreq.type);
2058
2059            if ((dreq.type == iss_t::XTN_READ) or
2060                (dreq.type == iss_t::XTN_WRITE))
2061                //log_dcache_transaction_file << xtn_str(dreq.addr>>2);
2062                switch (dreq.addr>>2)
2063                {
2064                case iss_t::XTN_DCACHE_INVAL : log_dcache_transaction_file << " INVAL"; break;
2065                case iss_t::XTN_SYNC         : log_dcache_transaction_file << " SYNC"; break;
2066                default                      : log_dcache_transaction_file << " invalid"; break;
2067                }                                                                           
2068
2069            log_dcache_transaction_file << std::endl;
2070
2071            // printf("[%d] @ %.8x be %.1x W %.8x R %.8x error %d - %s"
2072            //        ,(uint32_t)m_cpt_total_cycles
2073            //        ,(uint32_t)dreq.addr
2074            //        ,(uint32_t)dreq.be
2075            //        ,(uint32_t)dreq.wdata
2076            //        ,(uint32_t)drsp.rdata
2077            //        ,(uint32_t)drsp.error
2078            //        ,type_str(dreq.type));
2079            // if ((dreq.type == iss_t::XTN_READ) or
2080            //     (dreq.type == iss_t::XTN_WRITE))
2081            //     //     printf(" %s",xtn_str(dreq.addr>>2));
2082            //     switch (dreq.addr>>2)
2083            //     {
2084            //     case iss_t::XTN_DCACHE_INVAL : printf(" INVAL"); break;
2085            //     case iss_t::XTN_SYNC         : printf(" SYNC"); break;
2086            //     default                      : printf(" invalid"); break;
2087            //     }                                                                           
2088            // printf("\n");
2089        }
2090#endif //CC_XCACHE_WRAPPER_DEBUG_DCACHE_TRANSACTION
2091
2092        ////////////////////////////////////////////////////////////////////////////
2093        // This CLEANUP FSM controls the transmission of the cleanup transactions
2094        // on the coherence network. It controls the following ressources:
2095        // - r_cleanup_fsm
2096        // - r_dcache_cleanup_req (reset)
2097        // - r_icache_cleanup_req (reset)
2098        //
2099        // This FSM handles cleanup requests from both the DCACHE FSM & ICACHE FSM
2100        // - Instruction Cleanup  : r_icache_cleanup_req
2101        // - Data Cleanup         : r_dcache_cleanup_req
2102        // In case of simultaneous requests, the data request have highest priority.
2103        // There is only one cleanup transaction at a given time (sequencial behavior)
2104        // because the same FSM controls both command & response.
2105        // The the r_icache_cleanup_req & r_dcache_cleanup_req are reset only
2106        // when the response packet is received.
2107        // Error handling :
2108        // As the coherence trafic is controled by hardware, errors are not reported
2109        // to software : In case of errors, the simulation stops.
2110        ////////////////////////////////////////////////////////////////////////////
2111
2112        switch (r_cleanup_fsm) {
2113
2114            case CLEANUP_IDLE:
2115            {   
2116                if ( p_vci_ini_c.cmdack )
2117                {
2118                    if      (r_dcache_cleanup_req)      r_cleanup_fsm = CLEANUP_DCACHE;
2119                    else if (r_icache_cleanup_req)      r_cleanup_fsm = CLEANUP_ICACHE;
2120                }
2121                break;
2122            }
2123            case CLEANUP_DCACHE:
2124            {
2125                if ( p_vci_ini_c.rspval )
2126                {
2127                    PRINTF("      * <CLEANUP> rerror : %d (%d)\n",(uint32_t)p_vci_ini_c.rerror.read(),0x2 & ( (1 << vci_param::E) - 1));
2128
2129                    ASSERT(p_vci_ini_c.reop and (p_vci_ini_c.rtrdid.read() == TYPE_DATA_CLEANUP),
2130                            "illegal response packet received for a cleanup transaction");
2131                    ASSERT( (p_vci_ini_c.rerror.read()&0x1) == vci_param::ERR_NORMAL,
2132                           "error signaled in a cleanup response" );
2133                   
2134                    r_cleanup_fsm = CLEANUP_IDLE;
2135                    r_dcache_cleanup_req = false;
2136                    // m_cpt_cc_cleanup_data++; TODO
2137                }
2138                break;
2139            }
2140            case CLEANUP_ICACHE:
2141            {
2142                if ( p_vci_ini_c.rspval )
2143                {
2144                    PRINTF("      * <CLEANUP> rerror : %d (%d)\n",(uint32_t)p_vci_ini_c.rerror.read(),0x2 & ( (1 << vci_param::E) - 1));
2145
2146                    ASSERT(p_vci_ini_c.reop and (p_vci_ini_c.rtrdid.read() == TYPE_INS_CLEANUP),
2147                           "illegal response packet received for a cleanup transaction");
2148                    ASSERT( (p_vci_ini_c.rerror.read()&0x1) == vci_param::ERR_NORMAL,
2149                           "error signaled in a cleanup response" );
2150                   
2151                    r_cleanup_fsm = CLEANUP_IDLE;
2152                    r_icache_cleanup_req = false;
2153                    // m_cpt_cc_cleanup_ins++; TODO
2154                }
2155                break;
2156            }
2157        } // end switch r_cleanup_fsm   
2158
2159        ////////////////////////////////////////////////////////////////////////////
2160        // The VCI_CMD FSM controls the following ressources:
2161        // - r_vci_cmd_fsm
2162        // - r_vci_cmd_min
2163        // - r_vci_cmd_max
2164        // - r_vci_cmd_cpt
2165        // - wbuf (reset)
2166        // - r_icache_miss_req (reset)
2167        // - r_icache_unc_req (reset)
2168        // - r_dcache_miss_req (reset)
2169        // - r_dcache_sc_req (reset)
2170        //
2171        // This FSM handles requests from both the DCACHE FSM & the ICACHE FSM.
2172        // There is 7 request types, with the following priorities :
2173        // 1 - Data Read Miss         : r_dcache_miss_req and miss in the write buffer
2174        // 2 - Data Read Uncachable   : r_dcache_unc_req  and miss in the write buffer
2175        // 3 - Instruction Miss       : r_icache_miss_req and miss in the write buffer
2176        // 4 - Instruction Uncachable : r_icache_unc_req  and miss in the write buffer
2177        // 5 - Data Write             : r_wbuf.rok()     
2178        // 6 - Data Store Conditionnal: r_dcache_sc_req
2179        // There is at most one (CMD/RSP) VCI transaction, as both CMD_FSM
2180        // and RSP_FSM exit simultaneously the IDLE state.
2181        //
2182        // VCI formats:
2183        // According to the VCI advanced specification, all read requests packets
2184        // (read Uncached, Miss data, Miss instruction) are one word packets.
2185        // For write burst packets, all words must be in the same cache line,
2186        // and addresses must be contiguous (the BE field is 0 in case of "holes").
2187        //////////////////////////////////////////////////////////////////////////////
2188
2189        r_vci_cmd_dcache_prior = not r_vci_cmd_dcache_prior;
2190
2191        switch (r_vci_cmd_fsm) {
2192
2193            case CMD_IDLE:
2194                {
2195                // if (r_vci_rsp_fsm != RSP_IDLE) break;
2196
2197                size_t  min;
2198                size_t  max;
2199
2200                r_vci_cmd_cpt = 0;
2201
2202                // Requests :
2203
2204                // multi_write_buffer access is conditionnal with dcache_miss_req and icache_miss_req
2205
2206#if   (CC_XCACHE_WRAPPER_VCI_CMD_PRIORITY==1)
2207                //  1) two access authorized
2208                bool dcache_miss_req =  r_dcache_miss_req;
2209                bool icache_miss_req =  r_icache_miss_req;
2210#elif (CC_XCACHE_WRAPPER_VCI_CMD_PRIORITY==2)
2211                //  2) one access with static priority (dcache prior)
2212                bool dcache_miss_req = r_dcache_miss_req; // dcache prior
2213                bool icache_miss_req = not dcache_miss_req and r_icache_miss_req;
2214#elif (CC_XCACHE_WRAPPER_VCI_CMD_PRIORITY==3)
2215                //  3) one access with static priority (icache prior)
2216                bool icache_miss_req = r_icache_miss_req;
2217                bool dcache_miss_req = not icache_miss_req and r_dcache_miss_req; // dcache prior
2218#elif (CC_XCACHE_WRAPPER_VCI_CMD_PRIORITY==4)
2219                //  4) one access with round robin priority
2220                bool dcache_miss_req = ((r_dcache_miss_req and not r_icache_miss_req) or // only dcache
2221                                        (r_dcache_miss_req and r_vci_cmd_dcache_prior)); // dcache prior
2222                bool icache_miss_req = not dcache_miss_req and r_icache_miss_req;
2223#else
2224#error "Invalid value to CC_XCACHE_WRAPPER_VCI_CMD_PRIORITY"
2225#endif
2226                // 1 - Data Read
2227                if (dcache_miss_req and r_wbuf.miss(r_dcache_addr_save))
2228                {
2229                    r_vci_cmd_fsm = CMD_DATA_MISS;
2230                    r_dcache_miss_req = false;
2231                    m_cpt_dmiss_transaction++;
2232                }
2233
2234                // 2 - Data Read Uncachable
2235                else if ( r_dcache_unc_req )
2236                {
2237                    r_vci_cmd_fsm = CMD_DATA_UNC;
2238                    r_dcache_unc_req = false;
2239                 // m_cpt_data_unc_transaction++;
2240                }
2241
2242                // 3 - Instruction Miss
2243                else if (icache_miss_req and r_wbuf.miss(r_icache_addr_save))
2244                {
2245                    r_vci_cmd_fsm = CMD_INS_MISS;
2246                    r_icache_miss_req = false;
2247                    m_cpt_imiss_transaction++;
2248                }
2249
2250                // 4 - Instruction Uncachable
2251                else if ( r_icache_unc_req )
2252                {
2253                    r_vci_cmd_fsm = CMD_INS_UNC;
2254                    r_icache_unc_req = false;
2255                 // m_cpt_ins_unc_transaction++;
2256                }
2257
2258                // 5 - Data Write
2259                else if ( r_wbuf.rok(&min, &max) )
2260                {
2261                    r_vci_cmd_fsm = CMD_DATA_WRITE;
2262                    r_vci_cmd_cpt = min;
2263                    r_vci_cmd_min = min;
2264                    r_vci_cmd_max = max;
2265                    m_cpt_data_write_transaction++;
2266                    m_length_write_transaction += (max-min+1);
2267                }
2268
2269                // 6 - Data Store Conditionnal
2270                else if ( r_dcache_sc_req )
2271                {
2272                    r_vci_cmd_fsm = CMD_DATA_SC;
2273                    r_vci_cmd_max = 1;
2274                    m_cpt_unc_transaction++;
2275                    r_dcache_sc_req = false;
2276                }
2277
2278                break;
2279                }
2280            case CMD_DATA_WRITE:
2281                if ( p_vci_ini_rw.cmdack.read() ) {
2282                    r_vci_cmd_cpt = r_vci_cmd_cpt + 1;
2283                    if (r_vci_cmd_cpt == r_vci_cmd_max) {
2284                        r_vci_cmd_fsm = CMD_IDLE ;
2285                        r_wbuf.sent() ;
2286                    }
2287                }
2288                break;
2289
2290            case CMD_DATA_SC:
2291                if ( p_vci_ini_rw.cmdack.read() ) {
2292                    r_vci_cmd_cpt = r_vci_cmd_cpt + 1;
2293                    if (r_vci_cmd_cpt == r_vci_cmd_max) {
2294                        r_vci_cmd_fsm = CMD_IDLE ;
2295                    }
2296                }
2297                break;
2298            case CMD_INS_MISS:
2299            case CMD_INS_UNC:
2300            case CMD_DATA_MISS:
2301            case CMD_DATA_UNC:
2302                if ( p_vci_ini_rw.cmdack.read() ) {
2303                    r_vci_cmd_fsm = CMD_IDLE;
2304                }
2305                break;
2306
2307        } // end  switch r_vci_cmd_fsm
2308
2309        //////////////////////////////////////////////////////////////////////////
2310        // The VCI_RSP FSM controls the following ressources:
2311        // - r_vci_rsp_fsm:
2312        // - r_icache_miss_buf[m_icache_words]
2313        // - r_dcache_miss_buf[m_dcache_words]
2314        // - r_vci_rsp_data_error set
2315        // - r_vci_rsp_ins_error set
2316        // - r_vci_rsp_cpt
2317        // In order to have only one active VCI transaction, this VCI_RSP_FSM
2318        // is synchronized with the VCI_CMD FSM, and both FSMs exit the
2319        // IDLE state simultaneously.
2320        //
2321        // VCI formats:
2322        // This component accepts single word or multi-word response packets for
2323        // write response packets.
2324        //
2325        // Error handling:
2326        // This FSM analyzes the VCI error code and signals directly the
2327        // Write Bus Error.
2328        // In case of Read Data Error, the VCI_RSP FSM sets the r_vci_rsp_data_error
2329        // flip_flop and the error is signaled by the DCACHE FSM. 
2330        // In case of Instruction Error, the VCI_RSP FSM sets the r_vci_rsp_ins_error
2331        // flip_flop and the error is signaled by the DCACHE FSM. 
2332        // In case of Cleanup Error, the simulation stops with an error message...
2333        //////////////////////////////////////////////////////////////////////////
2334
2335        switch (r_vci_rsp_fsm) {
2336
2337            case RSP_IDLE:
2338
2339                if( p_vci_ini_rw.rspval.read() )
2340                {
2341                    PRINTF("      * <RSP> have rsp - trdid : %x\n",(uint32_t)p_vci_ini_rw.rtrdid.read());
2342
2343                    r_vci_rsp_cpt = 0;
2344
2345                    if ((p_vci_ini_rw.rtrdid.read()>>(vci_param::T-1)) != 0 )
2346                        r_vci_rsp_fsm = RSP_DATA_WRITE;
2347                    else
2348                    {
2349                        switch (p_vci_ini_rw.rtrdid.read())
2350                        {
2351                        case TYPE_INS_MISS     : r_vci_rsp_fsm = RSP_INS_MISS;     break;
2352                        case TYPE_INS_UNC      : r_vci_rsp_fsm = RSP_INS_UNC;      break;
2353                        case TYPE_DATA_MISS    : r_vci_rsp_fsm = RSP_DATA_MISS;    break;
2354                        case TYPE_DATA_UNC     : r_vci_rsp_fsm = RSP_DATA_UNC;     break;
2355                        case TYPE_DATA_SC      : r_vci_rsp_fsm = RSP_DATA_SC;      break;
2356                        default :
2357                            {
2358                                ASSERT(false, "Unexpected response");
2359                            }
2360                        }
2361                    }
2362                }
2363                break;
2364
2365            case RSP_INS_MISS:
2366
2367                m_cost_imiss_transaction++;
2368                PRINTF("      * <RSP> rspval/ack : %d - %d\n",(uint32_t)p_vci_ini_rw.rspval.read(), (uint32_t)r_vci_rsp_ack);
2369
2370                if (p_vci_ini_rw.rspval.read() and r_vci_rsp_ack)
2371                {
2372                    PRINTF("      * <RSP> have rsp - r_vci_rsp_cpt : %d/%d\n",(uint32_t)r_vci_rsp_cpt.read(),(uint32_t)m_icache_words);
2373                    PRINTF("      * <RSP> ins : %x\n",(int)p_vci_ini_rw.rdata.read());
2374
2375                    ASSERT( (r_vci_rsp_cpt < m_icache_words),
2376                            "The VCI response packet for instruction miss is too long" );
2377                    r_vci_rsp_cpt = r_vci_rsp_cpt + 1;
2378                    CACHE_MISS_BUF_RSP_PUSH(i,r_vci_rsp_cpt,(data_t)p_vci_ini_rw.rdata.read());
2379                    if ( p_vci_ini_rw.reop.read() )
2380                    {
2381                        PRINTF("      * <RSP> have reop\n");
2382                        ASSERT( ((r_vci_rsp_cpt.read() == m_icache_words - 1) or
2383                                 p_vci_ini_rw.rerror.read() or
2384                                 (r_vci_rsp_ins_error.read()&0x1)),
2385                                "The VCI response packet for instruction miss is too short");
2386                        r_vci_rsp_cpt    = 0;
2387                        r_vci_rsp_fsm    = RSP_IDLE;
2388
2389                    }
2390                    if ( (p_vci_ini_rw.rerror.read()&0x1) != vci_param::ERR_NORMAL ) r_vci_rsp_ins_error = true;
2391                }
2392                break;
2393
2394            case RSP_INS_UNC:
2395
2396                m_cost_imiss_transaction++;
2397                if (p_vci_ini_rw.rspval.read() and r_vci_rsp_ack)
2398                {
2399                    ASSERT(p_vci_ini_rw.reop.read(),
2400                           "illegal VCI response packet for uncached instruction");
2401
2402                    CACHE_MISS_BUF_RSP_PUSH(i,0,(data_t)p_vci_ini_rw.rdata.read());
2403
2404                    r_vci_rsp_fsm = RSP_IDLE;
2405
2406                    if ( (p_vci_ini_rw.rerror.read()&0x1) != vci_param::ERR_NORMAL ) r_vci_rsp_ins_error = true;
2407                }
2408                break;
2409
2410            case RSP_DATA_MISS:
2411
2412                m_cost_dmiss_transaction++;
2413                if (p_vci_ini_rw.rspval.read() and r_vci_rsp_ack)
2414                {
2415                    PRINTF("      * <RSP> have rspval - error : %d\n",(int)p_vci_ini_rw.rerror.read());
2416
2417                    ASSERT(r_vci_rsp_cpt < m_dcache_words,
2418                           "illegal VCI response packet for data read miss");
2419                    r_vci_rsp_cpt = r_vci_rsp_cpt + 1;
2420
2421                    CACHE_MISS_BUF_RSP_PUSH(d,r_vci_rsp_cpt,(data_t)p_vci_ini_rw.rdata.read());
2422
2423                    if ( p_vci_ini_rw.reop.read() ) {
2424                        ASSERT( ((r_vci_rsp_cpt == m_dcache_words - 1)
2425                                 or (p_vci_ini_rw.rerror.read()&0x1)
2426                                 or r_vci_rsp_data_error.read()),
2427                                "illegal VCI response packet for data read miss");
2428                        r_vci_rsp_cpt     = 0;
2429                        r_vci_rsp_fsm     = RSP_IDLE;
2430                    }
2431                    if ( (p_vci_ini_rw.rerror.read()&0x1) != vci_param::ERR_NORMAL ) r_vci_rsp_data_error = true;
2432                }
2433                break;
2434
2435            case RSP_DATA_WRITE:
2436
2437                m_cost_write_transaction++;
2438                if (p_vci_ini_rw.rspval.read())
2439                {
2440                    PRINTF("      * <RSP> have rspval - error : %d\n",(int)p_vci_ini_rw.rerror.read());
2441
2442                    ASSERT(p_vci_ini_rw.reop.read(),
2443                           "A VCI response packet must contain one flit for a write transaction");
2444                    r_vci_rsp_fsm = RSP_IDLE;
2445                    bool cached = r_wbuf.completed(p_vci_ini_rw.rtrdid.read() - (1<<(vci_param::T-1)) );
2446
2447                    PRINTF("      * <RSP> cached : %d\n",cached);
2448
2449                    if (not cached)
2450                        r_dcache_previous_unc = false;
2451
2452                    if ((p_vci_ini_rw.rerror.read()&0x1) != vci_param::ERR_NORMAL) m_iss.setWriteBerr();
2453                }
2454                break;
2455
2456            case RSP_DATA_UNC:
2457                m_cost_unc_transaction++;
2458                if (p_vci_ini_rw.rspval.read() and r_vci_rsp_ack)
2459                {
2460                    ASSERT(p_vci_ini_rw.reop.read(),
2461                           "illegal VCI response packet for data read uncached");
2462
2463                    CACHE_MISS_BUF_RSP_PUSH(d,0,(data_t)p_vci_ini_rw.rdata.read());
2464
2465                    r_vci_rsp_fsm = RSP_IDLE;
2466                    r_dcache_previous_unc = false;
2467
2468                    if ( (p_vci_ini_rw.rerror.read()&0x1) != vci_param::ERR_NORMAL ) r_vci_rsp_data_error = true;
2469                }
2470                break;
2471
2472            case RSP_DATA_SC:
2473                m_cost_unc_transaction++;
2474                if (p_vci_ini_rw.rspval.read() and r_vci_rsp_ack)
2475                {
2476                    ASSERT(p_vci_ini_rw.reop.read(),
2477                           "illegal VCI response packet for data SC");
2478
2479                    CACHE_MISS_BUF_RSP_PUSH(d,0,(data_t)p_vci_ini_rw.rdata.read());
2480
2481                    r_vci_rsp_fsm = RSP_IDLE;
2482                    r_dcache_previous_unc = false;
2483
2484                    if ( (p_vci_ini_rw.rerror.read()&0x1) != vci_param::ERR_NORMAL ) r_vci_rsp_data_error = true;
2485                }
2486                break;
2487
2488        } // end switch r_vci_rsp_fsm
2489
2490    } // end transition()
2491
2492    //////////////////////////////////////////////////////////////////////////////////
2493    tmpl(void)::genMoore()
2494    //////////////////////////////////////////////////////////////////////////////////
2495    {
2496
2497        // VCI initiator response
2498        switch ( r_cleanup_fsm.read() ) {
2499
2500            case CLEANUP_IDLE:
2501                p_vci_ini_c.rspack  = false;
2502                p_vci_ini_c.cmdval  = r_icache_cleanup_req || r_dcache_cleanup_req;
2503                if ( r_dcache_cleanup_req )
2504                {
2505                    p_vci_ini_c.address =  r_dcache_cleanup_line.read() * (m_dcache_words << 2);
2506                    p_vci_ini_c.trdid   = TYPE_DATA_CLEANUP;
2507                }
2508                else
2509                {
2510                    p_vci_ini_c.address =  r_icache_cleanup_line.read() * (m_icache_words << 2);
2511                    p_vci_ini_c.trdid   = TYPE_INS_CLEANUP;
2512                }
2513                p_vci_ini_c.wdata  = 0;
2514                p_vci_ini_c.be     = 0xF;
2515                p_vci_ini_c.plen   = 4;
2516                p_vci_ini_c.cmd    = vci_param::CMD_WRITE;
2517                p_vci_ini_c.pktid  = 0;
2518                p_vci_ini_c.srcid  = m_srcid_c;
2519                p_vci_ini_c.cons   = false;
2520                p_vci_ini_c.wrap   = false;
2521                p_vci_ini_c.contig = false;
2522                p_vci_ini_c.clen   = 0;
2523                p_vci_ini_c.cfixed = false;
2524                p_vci_ini_c.eop    = true;
2525                break;
2526
2527           case CLEANUP_DCACHE:
2528                p_vci_ini_c.rspack  = true;
2529                p_vci_ini_c.cmdval  = false;
2530                p_vci_ini_c.address = 0;
2531                p_vci_ini_c.wdata  = 0;
2532                p_vci_ini_c.be     = 0;
2533                p_vci_ini_c.plen   = 0;
2534                p_vci_ini_c.cmd    = vci_param::CMD_WRITE;
2535                p_vci_ini_c.trdid  = 0;
2536                p_vci_ini_c.pktid  = 0;
2537                p_vci_ini_c.srcid  = 0;
2538                p_vci_ini_c.cons   = false;
2539                p_vci_ini_c.wrap   = false;
2540                p_vci_ini_c.contig = false;
2541                p_vci_ini_c.clen   = 0;
2542                p_vci_ini_c.cfixed = false;
2543                p_vci_ini_c.eop = false;
2544                break;
2545
2546           case CLEANUP_ICACHE:
2547                p_vci_ini_c.rspack  = true;
2548                p_vci_ini_c.cmdval  = false;
2549                p_vci_ini_c.address = 0;
2550                p_vci_ini_c.wdata  = 0;
2551                p_vci_ini_c.be     = 0;
2552                p_vci_ini_c.plen   = 0;
2553                p_vci_ini_c.cmd    = vci_param::CMD_WRITE;
2554                p_vci_ini_c.trdid  = 0;
2555                p_vci_ini_c.pktid  = 0;
2556                p_vci_ini_c.srcid  = 0;
2557                p_vci_ini_c.cons   = false;
2558                p_vci_ini_c.wrap   = false;
2559                p_vci_ini_c.contig = false;
2560                p_vci_ini_c.clen   = 0;
2561                p_vci_ini_c.cfixed = false;
2562                p_vci_ini_c.eop = false;
2563                break;
2564           } // end switch r_cleanup_fsm
2565
2566        // VCI initiator command
2567
2568        switch (r_vci_cmd_fsm.read() ) {
2569
2570            case CMD_IDLE:
2571                p_vci_ini_rw.cmdval  = false;
2572                p_vci_ini_rw.address = 0;
2573                p_vci_ini_rw.wdata   = 0;
2574                p_vci_ini_rw.be      = 0;
2575                p_vci_ini_rw.plen    = 0;
2576                p_vci_ini_rw.cmd     = vci_param::CMD_NOP;
2577                p_vci_ini_rw.trdid   = 0;
2578                p_vci_ini_rw.pktid   = 0;
2579                p_vci_ini_rw.srcid   = 0;
2580                p_vci_ini_rw.cons    = false;
2581                p_vci_ini_rw.wrap    = false;
2582                p_vci_ini_rw.contig  = false;
2583                p_vci_ini_rw.clen    = 0;
2584                p_vci_ini_rw.cfixed  = false;
2585                p_vci_ini_rw.eop     = false;
2586
2587                break;
2588
2589            case CMD_DATA_UNC:
2590                p_vci_ini_rw.cmdval = true;
2591                p_vci_ini_rw.address = (addr_40) r_dcache_addr_save.read() & ~0x3;
2592                switch( r_dcache_type_save ) {
2593                    case iss_t::DATA_READ:
2594                        p_vci_ini_rw.wdata = 0;
2595                        p_vci_ini_rw.be  = r_dcache_be_save.read();
2596                        p_vci_ini_rw.cmd = vci_param::CMD_READ;
2597                        break;
2598                    case iss_t::DATA_LL:
2599                        p_vci_ini_rw.wdata = 0;
2600                        p_vci_ini_rw.be  = 0xF;
2601                        p_vci_ini_rw.cmd = vci_param::CMD_LOCKED_READ;
2602                        break;
2603                    default:
2604                        ASSERT(false,"this should not happen");
2605                }
2606                p_vci_ini_rw.plen = 4;
2607                p_vci_ini_rw.trdid  = TYPE_DATA_UNC;   // data cache uncached read
2608                p_vci_ini_rw.pktid  = 0;
2609                p_vci_ini_rw.srcid  = m_srcid_rw;
2610                p_vci_ini_rw.cons   = false;
2611                p_vci_ini_rw.wrap   = false;
2612                p_vci_ini_rw.contig = true;
2613                p_vci_ini_rw.clen   = 0;
2614                p_vci_ini_rw.cfixed = false;
2615                p_vci_ini_rw.eop    = true;
2616
2617                break;
2618
2619            case CMD_DATA_SC:
2620                p_vci_ini_rw.cmdval = true;
2621                p_vci_ini_rw.address = (addr_40) r_dcache_addr_save.read() & ~0x3;
2622                if(r_vci_cmd_max.read() == 3){
2623                    ASSERT(false, "Not handled yet");
2624                } else { // r_vci_cmd_cpt == 1
2625                    switch(r_vci_cmd_cpt.read()){
2626                        case 0:
2627                            p_vci_ini_rw.wdata = (uint32_t)(r_dcache_ll_data.read() & 0xFFFFFFFF);
2628                            break;
2629                        case 1:
2630                            p_vci_ini_rw.wdata = r_dcache_wdata_save.read();
2631                            break;
2632                    }
2633                }
2634                p_vci_ini_rw.be     = 0xF;
2635                p_vci_ini_rw.cmd    = vci_param::CMD_STORE_COND;
2636                p_vci_ini_rw.plen   = 4*(r_vci_cmd_max.read()+1);
2637                p_vci_ini_rw.trdid  = TYPE_DATA_SC;   // data cache uncached read
2638                p_vci_ini_rw.pktid  = 0;
2639                p_vci_ini_rw.srcid  = m_srcid_rw;
2640                p_vci_ini_rw.cons   = true;
2641                p_vci_ini_rw.wrap   = false;
2642                p_vci_ini_rw.contig = false;
2643                p_vci_ini_rw.clen   = 0;
2644                p_vci_ini_rw.cfixed = false;
2645                p_vci_ini_rw.eop    = (r_vci_cmd_cpt.read() == r_vci_cmd_max.read());
2646
2647                break;
2648
2649            case CMD_DATA_WRITE:
2650                p_vci_ini_rw.cmdval  = true;
2651                p_vci_ini_rw.address = r_wbuf.getAddress(r_vci_cmd_cpt)&~0x3;
2652                p_vci_ini_rw.wdata   = r_wbuf.getData(r_vci_cmd_cpt);
2653                p_vci_ini_rw.be      = r_wbuf.getBe(r_vci_cmd_cpt);
2654                p_vci_ini_rw.plen    = (r_vci_cmd_max - r_vci_cmd_min + 1)<<2;
2655                p_vci_ini_rw.cmd     = vci_param::CMD_WRITE;
2656                p_vci_ini_rw.trdid   = r_wbuf.getIndex() + (1<<(vci_param::T-1));
2657                p_vci_ini_rw.pktid   = 0;
2658                p_vci_ini_rw.srcid   = m_srcid_rw;
2659                p_vci_ini_rw.cons    = false;
2660                p_vci_ini_rw.wrap    = false;
2661                p_vci_ini_rw.contig  = true;
2662                p_vci_ini_rw.clen    = 0;
2663                p_vci_ini_rw.cfixed  = false;
2664                p_vci_ini_rw.eop     = (r_vci_cmd_cpt == r_vci_cmd_max);
2665
2666                break;
2667
2668            case CMD_DATA_MISS:
2669                p_vci_ini_rw.cmdval = true;
2670                p_vci_ini_rw.address = r_dcache_addr_save.read() & (addr_40) m_dcache_yzmask;
2671                p_vci_ini_rw.be     = 0xF;
2672                p_vci_ini_rw.plen   = m_dcache_words << 2;
2673                p_vci_ini_rw.cmd    = vci_param::CMD_READ;
2674                p_vci_ini_rw.trdid  = TYPE_DATA_MISS;   // data cache cached read
2675                p_vci_ini_rw.pktid  = 0;
2676                p_vci_ini_rw.srcid  = m_srcid_rw;
2677                p_vci_ini_rw.cons   = false;
2678                p_vci_ini_rw.wrap   = false;
2679                p_vci_ini_rw.contig = true;
2680                p_vci_ini_rw.clen   = 0;
2681                p_vci_ini_rw.cfixed = false;
2682                p_vci_ini_rw.eop = true;
2683
2684                break;
2685
2686            case CMD_INS_MISS:
2687                p_vci_ini_rw.cmdval = true;
2688                p_vci_ini_rw.address = r_icache_addr_save.read() & (addr_40) m_icache_yzmask;
2689                p_vci_ini_rw.be     = 0xF;
2690                p_vci_ini_rw.plen   = m_icache_words << 2;
2691                p_vci_ini_rw.cmd    = vci_param::CMD_READ;
2692                p_vci_ini_rw.trdid  = TYPE_INS_MISS;   // ins cache cached read
2693                p_vci_ini_rw.pktid  = 0;
2694                p_vci_ini_rw.srcid  = m_srcid_rw;
2695                p_vci_ini_rw.cons   = false;
2696                p_vci_ini_rw.wrap   = false;
2697                p_vci_ini_rw.contig = true;
2698                p_vci_ini_rw.clen   = 0;
2699                p_vci_ini_rw.cfixed = false;
2700                p_vci_ini_rw.eop = true;
2701
2702                break;
2703
2704            case CMD_INS_UNC:
2705                p_vci_ini_rw.cmdval = true;
2706                p_vci_ini_rw.address = r_icache_addr_save.read() & ~0x3;
2707                p_vci_ini_rw.be     = 0xF;
2708                p_vci_ini_rw.plen   = 4;
2709                p_vci_ini_rw.cmd    = vci_param::CMD_READ;
2710                p_vci_ini_rw.trdid  = TYPE_INS_UNC;   // ins cache uncached read
2711                p_vci_ini_rw.pktid  = 0;
2712                p_vci_ini_rw.srcid  = m_srcid_rw;
2713                p_vci_ini_rw.cons   = false;
2714                p_vci_ini_rw.wrap   = false;
2715                p_vci_ini_rw.contig = true;
2716                p_vci_ini_rw.clen   = 0;
2717                p_vci_ini_rw.cfixed = false;
2718                p_vci_ini_rw.eop = true;
2719
2720                break;
2721
2722        } // end switch r_vci_cmd_fsm
2723
2724        bool ack;
2725
2726        switch (r_vci_rsp_fsm.read() ) {
2727        case RSP_IDLE       : ack = false; break;
2728        case RSP_DATA_WRITE : ack = true; break;
2729        case RSP_INS_MISS   :
2730        case RSP_INS_UNC    : ack = CACHE_MISS_BUF_RSP_ACK(i); break;
2731        case RSP_DATA_MISS  :
2732        case RSP_DATA_UNC   :
2733        case RSP_DATA_SC    : ack = CACHE_MISS_BUF_RSP_ACK(d); break;
2734        } // end switch r_vci_cmd_fsm
2735
2736        r_vci_rsp_ack       = ack;
2737        p_vci_ini_rw.rspack = ack;
2738       
2739        // VCI_TGT
2740
2741        switch ( r_vci_tgt_fsm.read() ) {
2742
2743            case TGT_IDLE:
2744            case TGT_UPDT_WORD:
2745            case TGT_UPDT_DATA:
2746                p_vci_tgt.cmdack  = true;
2747                p_vci_tgt.rspval  = false;
2748                break;
2749
2750            case TGT_RSP_BROADCAST:
2751                p_vci_tgt.cmdack  = false;
2752                p_vci_tgt.rspval  = not r_tgt_icache_req.read() and not r_tgt_dcache_req.read() and ( r_tgt_icache_rsp | r_tgt_dcache_rsp );
2753                p_vci_tgt.rsrcid  = r_tgt_srcid.read();
2754                p_vci_tgt.rpktid  = r_tgt_pktid.read();
2755                p_vci_tgt.rtrdid  = r_tgt_trdid.read();
2756                p_vci_tgt.rdata   = 0;
2757                p_vci_tgt.rerror  = 0x2 & ( (1 << vci_param::E) - 1); // Write OK
2758                p_vci_tgt.reop    = true;
2759                break;
2760
2761            case TGT_RSP_ICACHE:
2762                p_vci_tgt.cmdack  = false;
2763                p_vci_tgt.rspval  = not r_tgt_icache_req.read() and r_tgt_icache_rsp.read();
2764                p_vci_tgt.rsrcid  = r_tgt_srcid.read();
2765                p_vci_tgt.rpktid  = r_tgt_pktid.read();
2766                p_vci_tgt.rtrdid  = r_tgt_trdid.read();
2767                p_vci_tgt.rdata   = 0;
2768                p_vci_tgt.rerror  = 0x2 & ( (1 << vci_param::E) - 1); // Write OK
2769                p_vci_tgt.reop    = true;
2770                break;
2771
2772            case TGT_RSP_DCACHE:
2773                p_vci_tgt.cmdack  = false;
2774                p_vci_tgt.rspval  = not r_tgt_dcache_req.read() and r_tgt_dcache_rsp.read();
2775                p_vci_tgt.rsrcid  = r_tgt_srcid.read();
2776                p_vci_tgt.rpktid  = r_tgt_pktid.read();
2777                p_vci_tgt.rtrdid  = r_tgt_trdid.read();
2778                p_vci_tgt.rdata   = 0;
2779                p_vci_tgt.rerror  = 0x2 & ( (1 << vci_param::E) - 1); // Write OK
2780                p_vci_tgt.reop    = true;
2781                break;
2782
2783            case TGT_REQ_BROADCAST:
2784            case TGT_REQ_ICACHE:
2785            case TGT_REQ_DCACHE:
2786                p_vci_tgt.cmdack  = false;
2787                p_vci_tgt.rspval  = false;
2788                break;
2789
2790        } // end switch TGT_FSM
2791    } // end genMoore()
2792
2793    //////////////////////////////////////////////////////////////////////////////////
2794    tmpl(void)::stop_simulation (uint32_t nb_frz_cycles)
2795    //////////////////////////////////////////////////////////////////////////////////
2796    {
2797#if CC_XCACHE_WRAPPER_STOP_SIMULATION
2798        if (nb_frz_cycles == 0)
2799            {
2800                PRINTF("CC_XCACHE_WRAPPER \"%s\" : don't stop the simulation.\n",name().c_str());
2801                m_stop_simulation = false;
2802            }
2803        else
2804            {
2805                PRINTF("CC_XCACHE_WRAPPER \"%s\" : stop the simulation after %d cycles.\n",name().c_str(),nb_frz_cycles);
2806                m_stop_simulation = true;
2807                m_stop_simulation_nb_frz_cycles_max = nb_frz_cycles;
2808            }
2809#else
2810        std::cout << "CC_XCACHE_WRAPPER \"" << name() << "\" : flag CC_XCACHE_WRAPPER_STOP_SIMULATION is unset, you can't use stop_simulation." << std::endl;
2811#endif // CC_XCACHE_WRAPPER_STOP_SIMULATION
2812       
2813    }
2814
2815}} // end namespace
2816
2817// Local Variables:
2818// tab-width: 4
2819// c-basic-offset: 4
2820// c-file-offsets:((innamespace . 0)(inline-open . 0))
2821// indent-tabs-mode: nil
2822// End:
2823
2824// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
Note: See TracBrowser for help on using the repository browser.