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

Last change on this file since 188 was 188, checked in by alain, 12 years ago

A maitainable version removing the multi-caches feature.

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