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

Last change on this file since 82 was 82, checked in by guthmull, 14 years ago

Add broadcast limitation compatibility, indicate the type of response when possible

  • 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: 89.7 KB
Line 
1/* -*- c++ -*-
2 *
3 * SOCLIB_LGPL_HEADER_BEGIN
4 *
5 * This file is part of SoCLib, GNU LGPLv2.1.
6 *
7 * SoCLib is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU Lesser General Public License as published
9 * by the Free Software Foundation; version 2.1 of the License.
10 *
11 * SoCLib is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with SoCLib; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 * 02110-1301 USA
20 *
21 * SOCLIB_LGPL_HEADER_END
22 *
23 * Copyright (c) UPMC, Lip6, SoC
24 *         Alain Greiner <alain.greiner@lip6.fr>, 2008
25 *
26 * Maintainers: alain eric.guthmuller@polytechnique.edu nipo
27 */
28
29/////////////////////////////////////////////////////////////////////////////
30// History
31// - 25/04/2008
32//   The existing vci_xcache component has been extended to include
33//   a VCI target port to support a directory based coherence protocol.
34//   Two types of packets can be send by the L2 cache to the L1 cache
35//   * INVALIDATE packets : length = 1
36//   * UPDATE packets : length = n + 2   
37//   The CLEANUP packets are sent by the L1 cache to the L2 cache,
38//   to signal a replaced cache line.
39// - 12/08/2008
40//   The vci_cc_xcache_wrapper component instanciates directly the processsor
41//   iss, in order to supress the processor/cache interface.
42//   According to the VCI advanced specification, this component uses one
43//   word VCI CMD packets for MISS transactions, and accept one word VCI RSP
44//   packets for Write burst  transactions.
45//   The write buffer has been modified to use the WriteBuffer object.
46//   A VCI write burst is constructed when two conditions are satisfied :
47//   The processor make strictly successive write requests, and they are
48//   in the same cache line. The write buffer performs re-ordering, to
49//   respect the contiguous addresses VCI constraint. In case of several
50//   WRITE_WORD requests in the same word, only the last request is conserved.
51//   In case of several WRITE_HALF or WRITE_WORD requests in the same word,
52//   the requests are merged in the same word. In case of uncached write
53//   requests, each request is transmited as a single VCI transaction.
54//   Both the data & instruction caches can be flushed in one single cycle.
55///////////////////////////////////////////////////////////////////////////////
56
57#include <cassert>
58#include "arithmetics.h"
59#include "../include/vci_cc_xcache_wrapper_v4.h"
60
61//#define DEBUG_CC_XCACHE_WRAPPER 1
62
63namespace soclib {
64namespace caba {
65
66#if DEBUG_CC_XCACHE_WRAPPER
67    namespace {
68        const char *dcache_fsm_state_str[] = {
69            "DCACHE_IDLE",
70            "DCACHE_WRITE_UPDT",
71            "DCACHE_WRITE_REQ",
72            "DCACHE_MISS_WAIT",
73            "DCACHE_MISS_UPDT",
74            "DCACHE_UNC_WAIT",
75            "DCACHE_SC_WAIT",
76            "DCACHE_INVAL",
77            "DCACHE_ERROR",
78            "DCACHE_CC_CHECK",
79            "DCACHE_CC_INVAL",
80            "DCACHE_CC_UPDT",
81            "DCACHE_CC_CLEANUP",
82        };
83        const char *icache_fsm_state_str[] = {
84            "ICACHE_IDLE",
85            "ICACHE_MISS_WAIT",
86            "ICACHE_MISS_UPDT",
87            "ICACHE_UNC_WAIT",
88            "ICACHE_ERROR",
89            "ICACHE_CC_CLEANUP",
90            "ICACHE_CC_CHECK",
91            "ICACHE_CC_INVAL",
92            "ICACHE_CC_UPDT",
93        };
94        const char *cmd_fsm_state_str[] = {
95            "CMD_IDLE",
96            "CMD_INS_MISS",
97            "CMD_INS_UNC",
98            "CMD_DATA_MISS",
99            "CMD_DATA_UNC",
100            "CMD_DATA_WRITE",
101            "CMD_DATA_SC",
102            "CMD_INS_CLEANUP",
103            "CMD_DATA_CLEANUP",
104        };
105        const char *rsp_fsm_state_str[] = {
106            "RSP_IDLE",
107            "RSP_INS_MISS",
108            "RSP_INS_UNC",
109            "RSP_DATA_MISS",
110            "RSP_DATA_UNC",
111            "RSP_DATA_WRITE",
112            "RSP_DATA_SC",
113            "RSP_INS_CLEANUP",
114            "RSP_DATA_CLEANUP",
115        };
116        const char *tgt_fsm_state_str[] = {
117            "TGT_IDLE",
118            "TGT_UPDT_WORD",
119            "TGT_UPDT_DATA",
120            "TGT_REQ_BROADCAST",
121            "TGT_REQ_ICACHE",
122            "TGT_REQ_DCACHE",
123            "TGT_RSP_BROADCAST",
124            "TGT_RSP_ICACHE",
125            "TGT_RSP_DCACHE",
126        };
127    }
128#endif
129
130#define tmpl(...)  template<typename vci_param, typename iss_t> __VA_ARGS__ VciCcXCacheWrapperV4<vci_param, iss_t>
131
132    using soclib::common::uint32_log2;
133
134    /////////////////////////////////
135    tmpl(/**/)::VciCcXCacheWrapperV4(
136            /////////////////////////////////
137            sc_module_name name,
138            int proc_id,
139            const soclib::common::MappingTable &mtp,
140            const soclib::common::MappingTable &mtc,
141            const soclib::common::IntTab &initiator_index_rw,
142            const soclib::common::IntTab &initiator_index_c,
143            const soclib::common::IntTab &target_index,
144            size_t icache_ways,
145            size_t icache_sets,
146            size_t icache_words,
147            size_t dcache_ways,
148            size_t dcache_sets,
149            size_t dcache_words )
150        :
151            soclib::caba::BaseModule(name),
152
153            p_clk("clk"),
154            p_resetn("resetn"),
155            p_vci_ini_rw("vci_ini_rw"),
156            p_vci_ini_c("vci_ini_c"),
157            p_vci_tgt("vci_tgt"),
158
159            m_cacheability_table(mtp.getCacheabilityTable<vci_addr_t>()),
160            m_segment(mtc.getSegment(target_index)),
161            m_iss(this->name(), proc_id),
162            m_srcid_rw(mtp.indexForId(initiator_index_rw)),
163            m_srcid_c(mtc.indexForId(initiator_index_c)),
164
165            m_dcache_ways(dcache_ways),
166            m_dcache_words(dcache_words),
167            m_dcache_yzmask((~0)<<(uint32_log2(dcache_words) + 2)),
168            m_icache_ways(icache_ways),
169            m_icache_words(icache_words),
170            m_icache_yzmask((~0)<<(uint32_log2(icache_words) + 2)),
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_rdata_save("r_dcache_rdata_save"),
177            r_dcache_ll_data("r_dcache_ll_data"),
178            r_dcache_ll_addr("r_dcache_ll_addr"),
179            r_dcache_ll_valid("r_dcache_ll_valid"),
180            r_dcache_type_save("r_dcache_type_save"),
181            r_dcache_be_save("r_dcache_be_save"),
182            r_dcache_cached_save("r_dcache_cached_save"),
183            r_dcache_cleanup_req("r_dcache_cleanup_req"),
184            r_dcache_cleanup_line("r_dcache_cleanup_line"),
185            r_dcache_miss_req("r_dcache_miss_req"),
186            r_dcache_unc_req("r_dcache_unc_req"),
187            r_dcache_write_req("r_dcache_write_req"),
188
189            r_icache_fsm("r_icache_fsm"),
190            r_icache_fsm_save("r_icache_fsm_save"),
191            r_icache_addr_save("r_icache_addr_save"),
192            r_icache_miss_req("r_icache_miss_req"),
193            r_icache_cleanup_req("r_icache_cleanup_req"),
194            r_icache_cleanup_line("r_icache_cleanup_line"),
195
196            r_vci_cmd_fsm("r_vci_cmd_fsm"),
197            r_vci_cmd_min("r_vci_cmd_min"),
198            r_vci_cmd_max("r_vci_cmd_max"),
199            r_vci_cmd_cpt("r_vci_cmd_cpt"),
200
201            r_vci_rsp_fsm("r_vci_rsp_fsm"),
202            r_vci_rsp_ins_error("r_vci_rsp_ins_error"),
203            r_vci_rsp_data_error("r_vci_rsp_data_error"),
204            r_vci_rsp_cpt("r_vci_rsp_cpt"),
205
206            r_icache_buf_unc_valid("r_icache_buf_unc_valid"),
207
208            r_vci_tgt_fsm("r_vci_tgt_fsm"),
209            r_tgt_addr("r_tgt_addr"),
210            r_tgt_word("r_tgt_word"),
211            r_tgt_update("r_tgt_update"),
212            r_tgt_srcid("r_tgt_srcid"),
213            r_tgt_pktid("r_tgt_pktid"),
214            r_tgt_trdid("r_tgt_trdid"),
215            r_tgt_icache_req("r_tgt_icache_req"),
216            r_tgt_dcache_req("r_tgt_dcache_req"),
217
218            r_wbuf("r_wbuf", dcache_words ),
219            r_icache("icache", icache_ways, icache_sets, icache_words),
220            r_dcache("dcache", dcache_ways, dcache_sets, dcache_words)
221
222            {
223                r_icache_miss_buf = new data_t[icache_words];
224                r_dcache_miss_buf = new data_t[dcache_words];
225                r_tgt_buf         = new data_t[dcache_words];
226                r_tgt_be          = new be_t[dcache_words];
227
228                SC_METHOD(transition);
229                dont_initialize();
230                sensitive << p_clk.pos();
231
232                SC_METHOD(genMoore);
233                dont_initialize();
234                sensitive << p_clk.neg();
235
236
237                typename iss_t::CacheInfo cache_info;
238                cache_info.has_mmu = false;
239                cache_info.icache_line_size = icache_words*sizeof(data_t);
240                cache_info.icache_assoc = icache_ways;
241                cache_info.icache_n_lines = icache_sets;
242                cache_info.dcache_line_size = dcache_words*sizeof(data_t);
243                cache_info.dcache_assoc = dcache_ways;
244                cache_info.dcache_n_lines = dcache_sets;
245                m_iss.setCacheInfo(cache_info);
246            } // end constructor
247
248    ///////////////////////////////////
249    tmpl(/**/)::~VciCcXCacheWrapperV4()
250        ///////////////////////////////////
251    {
252        delete [] r_icache_miss_buf;
253        delete [] r_dcache_miss_buf;
254        delete [] r_tgt_be;
255        delete [] r_tgt_buf;
256    }
257
258    ////////////////////////
259    tmpl(void)::print_cpi()
260        ////////////////////////
261    {
262        std::cout << "CPU " << m_srcid_rw << " : CPI = "
263            << (float)m_cpt_total_cycles/(m_cpt_total_cycles - m_cpt_frz_cycles) << std::endl ;
264    }
265    ////////////////////////
266    tmpl(void)::print_stats()
267        ////////////////////////
268    {
269        float run_cycles = (float)(m_cpt_total_cycles - m_cpt_frz_cycles);
270        std::cout << "------------------------------------" << std:: dec << std::endl;
271        std::cout << "CPU " << m_srcid_rw << " / Time = " << m_cpt_total_cycles << std::endl;
272        std::cout << "- CPI                = " << (float)m_cpt_total_cycles/run_cycles << std::endl ;
273        std::cout << "- READ RATE          = " << (float)m_cpt_read/run_cycles << std::endl ;
274        std::cout << "- WRITE RATE         = " << (float)m_cpt_write/run_cycles << std::endl;
275        std::cout << "- UNCACHED READ RATE = " << (float)m_cpt_unc_read/m_cpt_read << std::endl ;
276        std::cout << "- CACHED WRITE RATE  = " << (float)m_cpt_write_cached/m_cpt_write << std::endl ;
277        std::cout << "- IMISS_RATE         = " << (float)m_cpt_ins_miss/run_cycles << std::endl;
278        std::cout << "- DMISS RATE         = " << (float)m_cpt_data_miss/(m_cpt_read-m_cpt_unc_read) << std::endl ;
279        std::cout << "- INS MISS COST      = " << (float)m_cost_ins_miss_frz/m_cpt_ins_miss << std::endl;
280        std::cout << "- IMISS TRANSACTION  = " << (float)m_cost_imiss_transaction/m_cpt_imiss_transaction << std::endl;
281        std::cout << "- DMISS COST         = " << (float)m_cost_data_miss_frz/m_cpt_data_miss << std::endl;
282        std::cout << "- DMISS TRANSACTION  = " << (float)m_cost_dmiss_transaction/m_cpt_dmiss_transaction << std::endl;
283        std::cout << "- UNC COST           = " << (float)m_cost_unc_read_frz/m_cpt_unc_read << std::endl;
284        std::cout << "- UNC TRANSACTION    = " << (float)m_cost_unc_transaction/m_cpt_unc_transaction << std::endl;
285        std::cout << "- WRITE COST         = " << (float)m_cost_write_frz/m_cpt_write << std::endl;
286        std::cout << "- WRITE TRANSACTION  = " << (float)m_cost_write_transaction/m_cpt_write_transaction << std::endl;
287        std::cout << "- WRITE LENGTH       = " << (float)m_length_write_transaction/m_cpt_write_transaction << std::endl;
288    }
289
290    //////////////////////////
291    tmpl(void)::transition()
292        //////////////////////////
293    {
294        if ( ! p_resetn.read() ) {
295
296            m_iss.reset();
297
298            // FSM states
299            r_dcache_fsm = DCACHE_IDLE;
300            r_icache_fsm = ICACHE_IDLE;
301            r_vci_cmd_fsm = CMD_IDLE;
302            r_vci_rsp_fsm = RSP_IDLE;
303            r_vci_tgt_fsm = TGT_IDLE;
304
305            // write buffer & caches
306            r_wbuf.reset();
307            r_icache.reset();
308            r_dcache.reset();
309
310            // synchronisation flip-flops from ICACHE & DCACHE FSMs to VCI  FSMs
311            r_icache_miss_req    = false;
312            r_icache_unc_req     = false;
313            r_icache_cleanup_req = false;
314            r_dcache_miss_req    = false;
315            r_dcache_unc_req     = false;
316            r_dcache_sc_req      = false;
317            r_dcache_write_req   = false;
318            r_dcache_cleanup_req = false;
319
320            // synchronisation flip-flops from TGT FSM to ICACHE & DCACHE FSMs
321            r_tgt_icache_req     = false;
322            r_tgt_dcache_req     = false;
323
324            // internal messages in DCACHE et ICACHE FSMs
325            r_icache_inval_rsp   = false;
326            r_dcache_inval_rsp   = false;
327
328            // error signals from the VCI RSP FSM to the ICACHE or DCACHE FSMs
329            r_dcache_ll_valid      = false;
330            r_icache_buf_unc_valid = false;
331            r_vci_rsp_data_error   = false;
332            r_vci_rsp_ins_error    = false;
333
334            // activity counters
335            m_cpt_dcache_data_read  = 0;
336            m_cpt_dcache_data_write = 0;
337            m_cpt_dcache_dir_read  = 0;
338            m_cpt_dcache_dir_write = 0;
339            m_cpt_icache_data_read  = 0;
340            m_cpt_icache_data_write = 0;
341            m_cpt_icache_dir_read  = 0;
342            m_cpt_icache_dir_write = 0;
343
344            m_cpt_cc_update = 0;
345            m_cpt_cc_inval = 0;
346
347            m_cpt_frz_cycles = 0;
348            m_cpt_total_cycles = 0;
349
350            m_cpt_read = 0;
351            m_cpt_write = 0;
352            m_cpt_data_miss = 0;
353            m_cpt_ins_miss = 0;
354            m_cpt_unc_read = 0;
355            m_cpt_write_cached = 0;
356
357            m_cost_write_frz = 0;
358            m_cost_data_miss_frz = 0;
359            m_cost_unc_read_frz = 0;
360            m_cost_ins_miss_frz = 0;
361
362            m_cpt_imiss_transaction = 0;
363            m_cpt_dmiss_transaction = 0;
364            m_cpt_unc_transaction = 0;
365            m_cpt_write_transaction = 0;
366
367            m_cost_imiss_transaction = 0;
368            m_cost_dmiss_transaction = 0;
369            m_cost_unc_transaction = 0;
370            m_cost_write_transaction = 0;
371            m_length_write_transaction = 0;
372
373            return;
374        }
375
376#if DEBUG_CC_XCACHE_WRAPPER
377        std::cout << "--------------------------------------------" << std::endl;
378        std::cout << std::dec << "CC_XCACHE_WRAPPER " << m_srcid_rw << " / Time = " << m_cpt_total_cycles << std::endl;
379        std::cout             << " tgt fsm    = " << tgt_fsm_state_str[r_vci_tgt_fsm] << std::endl
380            << " dcache fsm = " << dcache_fsm_state_str[r_dcache_fsm] << std::endl
381            << " icache fsm = " << icache_fsm_state_str[r_icache_fsm] << std::endl
382            << " cmd fsm    = " << cmd_fsm_state_str[r_vci_cmd_fsm] << std::endl
383            << " rsp fsm    = " << rsp_fsm_state_str[r_vci_rsp_fsm] << std::endl;
384#endif
385
386        m_cpt_total_cycles++;
387
388        /////////////////////////////////////////////////////////////////////
389        // The TGT_FSM controls the following ressources:
390        // - r_vci_tgt_fsm
391        // - r_tgt_buf[nwords]
392        // - r_tgt_be[nwords]
393        // - r_tgt_update
394        // - r_tgt_word
395        // - r_tgt_addr
396        // - r_tgt_srcid
397        // - r_tgt_trdid
398        // - r_tgt_pktid
399        // All VCI commands must be CMD_WRITE.
400        // If the VCI address offset is null, the command is an invalidate
401        // request. It is an update request otherwise.
402        // The VCI_TGT FSM stores the external request arguments in the
403        // IDLE, UPDT_WORD & UPDT_DATA states. It sets the r_tgt_icache_req
404        // & r_tgt_dcache_req flip-flops to signal the external request to
405        // the ICACHE & DCACHE FSMs in the REQ state. It waits the completion
406        // of the update or invalidate request in the RSP state.
407        // -  for an invalidate request the VCI packet length is 1 word.
408        // The WDATA field contains the line index (i.e. the Z & Y fields).
409        // -  for an update request the VCI packet length is (n+2) words.
410        // The WDATA field of the first VCI word contains the line number.
411        // The WDATA field of the second VCI word contains the word index.
412        // The WDATA field of the n following words contains the values.
413        // -  for both invalidate & update requests, the VCI response
414        // is one single word.
415        // In case of errors in the VCI command packet, the simulation
416        // is stopped with an error message.
417        /////////////////////////////////////////////////////////////////////
418
419        switch(r_vci_tgt_fsm) {
420
421            case TGT_IDLE:
422                if ( p_vci_tgt.cmdval.read() )
423                {
424                    addr_40 address = p_vci_tgt.address.read();
425
426                    if ( p_vci_tgt.cmd.read() != vci_param::CMD_WRITE)
427                    {
428                        std::cout << "error in component VCI_CC_XCACHE_WRAPPER " << name() << std::endl;
429                        std::cout << "the received VCI command from " << std::dec << p_vci_tgt.srcid.read() << " is not a write" << std::endl;
430                        exit(0);
431                    }
432
433                    // multi-update or multi-invalidate for data type
434                    if ( ((address&0x3) != 0x3) && (! m_segment.contains(address)) )
435                    {
436                        std::cout << "error in component VCI_CC_XCACHE_WRAPPER " << name() << std::endl;
437                        std::cout << "out of segment VCI command received for a multi-updt or multi-inval request" << std::endl;
438                        exit(0);
439                    }
440
441                    r_tgt_addr = (((addr_40) ((p_vci_tgt.be.read() & 0x3) << 32)) |
442                                 ((addr_40) (p_vci_tgt.wdata.read()))) * m_dcache_words * 4;     
443                    r_tgt_srcid = p_vci_tgt.srcid.read();
444                    r_tgt_trdid = p_vci_tgt.trdid.read();
445                    r_tgt_pktid = p_vci_tgt.pktid.read();
446                    r_tgt_plen  = p_vci_tgt.plen.read();
447                   
448                    if ( (address&0x3) == 0x3 )   // broadcast invalidate for data or instruction type
449                    {
450                        if ( ! p_vci_tgt.eop.read() )
451                        {
452                            std::cout << "error in component VCI_CC_XCACHE_WRAPPER " << name() << std::endl;
453                            std::cout << "the BROADCAST INVALIDATE command length must be one word" << std::endl;
454                            exit(0);
455                        }
456                        r_tgt_update = false;
457                        r_tgt_brdcast= true;
458                        r_vci_tgt_fsm = TGT_REQ_BROADCAST;
459                        m_cpt_cc_inval++ ;
460                    }
461                    else                    // multi-update or multi-invalidate for data type
462                    {
463                        uint32_t cell = address - m_segment.baseAddress(); // addr_40
464                        r_tgt_brdcast = false;
465                        if (cell == 0)
466                        {                                       // invalidate data
467                            if ( ! p_vci_tgt.eop.read() )
468                            {
469                                std::cout << "error in component VCI_CC_XCACHE_WRAPPER " << name() << std::endl;
470                                std::cout << "the MULTI-INVALIDATE command length must be one word" << std::endl;
471                                exit(0);
472                            }
473                            r_tgt_update = false;
474                            r_vci_tgt_fsm = TGT_REQ_DCACHE;
475                            m_cpt_cc_inval++ ;
476                        }
477                        else if (cell == 4)                     // invalidate instruction
478                        {                         
479                            if ( ! p_vci_tgt.eop.read() )
480                            {
481                                std::cout << "error in component VCI_CC_VCACHE_WRAPPER " << name() << std::endl;
482                                std::cout << "the MULTI-INVALIDATE command length must be one word" << std::endl;
483                                exit(0);
484                            }
485                            r_tgt_update = false;
486                            r_vci_tgt_fsm = TGT_REQ_ICACHE;
487                            m_cpt_cc_inval++ ;
488                        }
489                        else if ( (cell == 8) || (cell==12) )    // update data or instruction
490                        {                               
491                            if ( p_vci_tgt.eop.read() )
492                            {
493                                std::cout << "error in component VCI_CC_VCACHE_WRAPPER " << name() << std::endl;
494                                std::cout << "the MULTI-UPDATE command length must be N+2 words" << std::endl;
495                                exit(0);
496                            }
497                            if(cell == 8)
498                                r_tgt_update_data = true;
499                            else
500                                r_tgt_update_data = false;
501                            r_tgt_update = true;
502                            r_vci_tgt_fsm = TGT_UPDT_WORD;
503                            m_cpt_cc_update++ ;
504                        }
505
506                    } // end if address
507                } // end if cmdval
508                break;
509
510            case TGT_UPDT_WORD:
511                if (p_vci_tgt.cmdval.read())
512                {
513                    if ( p_vci_tgt.eop.read() )
514                    {
515                        std::cout << "error in component VCI_CC_XCACHE_WRAPPER " << name() << std::endl;
516                        std::cout << "the MULTI-UPDATE command length must be N+2 words" << std::endl;
517                        exit(0);
518                    }
519                    for ( size_t i=0 ; i<m_dcache_words ; i++ ) r_tgt_be[i] = 0;
520                    r_tgt_word = p_vci_tgt.wdata.read(); // the first modified word index
521#ifdef COHERENCE_DEBUG
522                    std::cout << "PROC " << m_srcid_rw << " update, line : " << std::hex << r_tgt_addr.read() << " word : " << p_vci_tgt.wdata.read() << std::dec << std::endl;
523#endif
524                    r_vci_tgt_fsm = TGT_UPDT_DATA;
525                }
526                break;
527
528            case TGT_UPDT_DATA:
529                if (p_vci_tgt.cmdval.read())
530                {
531                    size_t word = r_tgt_word.read();
532                    if ( word >= m_dcache_words )
533                    {
534                        std::cout << "error in component VCI_CC_XCACHE_WRAPPER " << name() << std::endl;
535                        std::cout << "the reveived MULTI-UPDATE command length is wrong" << std::endl;
536                        exit(0);
537                    }
538#ifdef COHERENCE_DEBUG
539                    std::cout << "PROC " << m_srcid_rw << " update, data : " << p_vci_tgt.wdata.read() << " be : " << std::hex << p_vci_tgt.be.read() << std::dec << std::endl;
540#endif
541                    r_tgt_buf[word] = p_vci_tgt.wdata.read();
542                    r_tgt_be[word] = p_vci_tgt.be.read();
543                    r_tgt_word = word + 1;
544                    if (p_vci_tgt.eop.read()){
545                      if(r_tgt_update_data.read()){
546                        r_vci_tgt_fsm = TGT_REQ_DCACHE;
547                      } else {
548                        r_vci_tgt_fsm = TGT_REQ_ICACHE;
549                      }
550                    }
551                }
552                break;
553
554            case TGT_REQ_BROADCAST:
555                if ( !r_tgt_icache_req.read() && !r_tgt_dcache_req.read() )
556                {
557                    r_vci_tgt_fsm = TGT_RSP_BROADCAST;
558                    r_tgt_icache_req = true;
559                    r_tgt_dcache_req = true;
560                }
561                break;
562                ////////////////////
563            case TGT_REQ_ICACHE:
564                {
565                    if ( !r_tgt_icache_req.read() )
566                    {
567                        r_vci_tgt_fsm = TGT_RSP_ICACHE;
568                        r_tgt_icache_req = true;
569                    }
570                    break;
571                }
572
573            case TGT_REQ_DCACHE:
574                if ( !r_tgt_dcache_req.read() )
575                {
576                    r_vci_tgt_fsm = TGT_RSP_DCACHE;
577                    r_tgt_dcache_req = true;
578                }
579                break;
580
581            case TGT_RSP_BROADCAST:
582                if ( !r_tgt_icache_req.read() && !r_tgt_dcache_req.read() )
583                {
584                    // one response
585                    if ( !r_tgt_icache_rsp || !r_tgt_dcache_rsp )
586                    {
587                        if ( p_vci_tgt.rspack.read() )
588                        {
589                            r_vci_tgt_fsm = TGT_IDLE;
590                            r_tgt_icache_rsp = false;
591                            r_tgt_dcache_rsp = false;
592                        }
593                    }
594
595                    // if data and instruction have the inval line, need two responses 
596                    if ( r_tgt_icache_rsp && r_tgt_dcache_rsp )
597                    {
598                        if ( p_vci_tgt.rspack.read() )
599                        {
600                            r_tgt_icache_rsp = false; // only reset one for respond the second time
601                        }
602                    }
603
604                    // if there is no need for a response
605                    if ( !r_tgt_icache_rsp && !r_tgt_dcache_rsp )
606                    {
607                        r_vci_tgt_fsm = TGT_IDLE;
608                    }
609
610                }
611                break;
612                ////////////////////
613            case TGT_RSP_ICACHE:
614                {
615                    if ( (p_vci_tgt.rspack.read() || !r_tgt_icache_rsp.read()) && !r_tgt_icache_req.read() )
616                    {
617                        r_vci_tgt_fsm = TGT_IDLE;
618                        r_tgt_icache_rsp = false;
619                    }
620                    break;
621                }
622
623            case TGT_RSP_DCACHE:
624                {
625                    if ( (p_vci_tgt.rspack.read() || !r_tgt_dcache_rsp.read()) && !r_tgt_dcache_req.read() )
626                    {
627                        r_vci_tgt_fsm = TGT_IDLE;
628                        r_tgt_dcache_rsp = false;
629                    }
630                    break;
631                }
632        } // end switch TGT_FSM
633
634        /////////////////////////////////////////////////////////////////////
635        // The ICACHE FSM controls the following ressources:
636        // - r_icache_fsm
637        // - r_icache_fsm_save
638        // - r_icache instruction cache access
639        // - r_icache_addr_save
640        // - r_icache_miss_req set
641        // - r_icache_unc_req set
642        // - r_icache_buf_unc_valid set
643        // - r_vci_rsp_ins_error reset
644        // - r_tgt_icache_req reset
645        // - ireq & irsp structures for communication with the processor
646        //
647        // 1/ External requests (update or invalidate) have highest priority.
648        //    They are taken into account in the IDLE and WAIT states.
649        //    As external hit should be extremly rare on the ICACHE,
650        //    all external requests are handled as invalidate...
651        //    In case of external request the ICACHE FSM goes to the CC_CHECK
652        //    state to test the external hit, and returns in the
653        //    pre-empted state after completion.
654        // 2/ Processor requests are taken into account only in the IDLE state.
655        //    In case of MISS, or in case of uncached instruction, the FSM
656        //    writes the missing address line in the  r_icache_addr_save register
657        //    and sets the r_icache_miss_req or the r_icache_unc_req flip-flops.
658        //    These request flip-flops are reset by the VCI_RSP FSM
659        //    when the VCI transaction is completed and the r_icache_buf_unc_valid
660        //    is set in case of uncached access.
661        //    In case of bus error, the VCI_RSP FSM sets the r_vci_rsp_ins_error
662        //    flip-flop. It is reset by the ICACHE FSM.
663        ///////////////////////////////////////////////////////////////////////
664
665        typename iss_t::InstructionRequest  ireq = ISS_IREQ_INITIALIZER;
666        typename iss_t::InstructionResponse irsp = ISS_IRSP_INITIALIZER;
667
668        typename iss_t::DataRequest  dreq = ISS_DREQ_INITIALIZER;
669        typename iss_t::DataResponse drsp = ISS_DRSP_INITIALIZER;
670
671        m_iss.getRequests( ireq, dreq );
672
673#if DEBUG_CC_XCACHE_WRAPPER
674        std::cout << " Instruction Request: " << ireq << std::endl;
675#endif
676
677        switch(r_icache_fsm) {
678            /////////////////
679            case ICACHE_IDLE:
680                {
681                    if ( r_tgt_icache_req ) {   // external request
682                        if ( ireq.valid ) m_cost_ins_miss_frz++;
683                        r_icache_fsm = ICACHE_CC_CHECK;
684                        r_icache_fsm_save = r_icache_fsm.read();
685                        break;
686                    }
687                    if ( ireq.valid ) {
688                        data_t  icache_ins = 0;
689                        bool    icache_hit = false;
690                        bool    icache_cached = m_cacheability_table[(vci_addr_t)ireq.addr];
691                        // icache_hit & icache_ins evaluation
692                        if ( icache_cached ) {
693                            icache_hit = r_icache.read((vci_addr_t) ireq.addr, &icache_ins);
694                        } else {
695                            icache_hit = ( r_icache_buf_unc_valid && ((addr_40) ireq.addr == (addr_40)r_icache_addr_save) );
696                            icache_ins = r_icache_miss_buf[0];
697                        }
698                        if ( ! icache_hit ) {
699                            m_cpt_ins_miss++;
700                            m_cost_ins_miss_frz++;
701                            r_icache_addr_save = (addr_40) ireq.addr;
702                            if ( icache_cached ) {
703                                r_icache_fsm = ICACHE_MISS_WAIT;
704                                r_icache_miss_req = true;
705                            } else {
706                                r_icache_fsm = ICACHE_UNC_WAIT;
707                                r_icache_unc_req = true;
708                            }
709                        } else {
710                            r_icache_buf_unc_valid = false;
711                        }
712                        m_cpt_icache_dir_read += m_icache_ways;
713                        m_cpt_icache_data_read += m_icache_ways;
714                        irsp.valid          = icache_hit;
715                        irsp.instruction    = icache_ins;
716                    }
717                    break;
718                }
719                //////////////////////
720            case ICACHE_MISS_WAIT:
721                {
722                    m_cost_ins_miss_frz++;
723                    if ( r_tgt_icache_req ) {   // external request
724                        r_icache_fsm = ICACHE_CC_CHECK;
725                        r_icache_fsm_save = r_icache_fsm.read();
726                        break;
727                    }
728                    if ( !r_icache_miss_req && !r_icache_inval_rsp ) { // Miss read response and no invalidation
729                        if ( r_vci_rsp_ins_error ) {
730                            r_icache_fsm = ICACHE_ERROR;
731                        } else {
732                            r_icache_fsm = ICACHE_MISS_UPDT;
733                        }
734                    }
735                    if ( !r_icache_miss_req && r_icache_inval_rsp ) { // Miss read response and invalidation
736                        if ( r_vci_rsp_ins_error ) {
737                            r_icache_inval_rsp = false;
738                            r_icache_fsm = ICACHE_ERROR;
739                        } else {
740                            r_icache_inval_rsp = false;
741                            r_icache_fsm = ICACHE_CC_CLEANUP;
742                        }
743                    }
744                    break;
745                }
746                /////////////////////
747            case ICACHE_UNC_WAIT:
748                {
749                    m_cost_ins_miss_frz++;
750                    if ( r_tgt_icache_req ) {   // external request
751                        r_icache_fsm = ICACHE_CC_CHECK;
752                        r_icache_fsm_save = r_icache_fsm.read();
753                        break;
754                    }
755                    if ( !r_icache_unc_req ) {
756                        if ( r_vci_rsp_ins_error ) {
757                            r_icache_fsm = ICACHE_ERROR;
758                        } else {
759                            r_icache_fsm = ICACHE_IDLE;
760                            r_icache_buf_unc_valid = true;
761                        }
762                    }
763                    break;
764                }
765                //////////////////
766            case ICACHE_ERROR:
767                {
768                    r_icache_fsm = ICACHE_IDLE;
769                    r_vci_rsp_ins_error = false;
770                    irsp.error          = true;
771                    irsp.valid          = true;
772                    break;
773                }
774                //////////////////////
775            case ICACHE_MISS_UPDT:
776                {
777                    if ( r_tgt_icache_req ) {   // external request
778                        r_icache_fsm = ICACHE_CC_CHECK;
779                        r_icache_fsm_save = r_icache_fsm.read();
780                        break;
781                    }
782                    if(!r_icache_cleanup_req.read() && !r_icache_inval_rsp){
783                        vci_addr_t ad   = 0;
784                        ad              = (vci_addr_t) r_icache_addr_save.read();
785                        data_t*   buf   = r_icache_miss_buf;
786                        vci_addr_t victim_index = 0;
787                        m_cpt_icache_dir_write++;
788                        m_cpt_icache_data_write++;
789                        if ( ireq.valid ) m_cost_ins_miss_frz++;
790
791                        r_icache_cleanup_req  = r_icache.update(ad, buf, &victim_index);
792                        r_icache_cleanup_line = (addr_40) victim_index;
793
794                        r_icache_fsm        = ICACHE_IDLE;
795                        break;
796                    }
797                    if(r_icache_inval_rsp){
798                        if ( ireq.valid ) m_cost_ins_miss_frz++;
799                        r_icache_inval_rsp  = false;
800                        r_icache_fsm = ICACHE_CC_CLEANUP;
801                        break;
802                    }
803                    if ( ireq.valid ) m_cost_ins_miss_frz++;
804                }
805                ////////////////////
806            case ICACHE_CC_CLEANUP:
807                {
808                    // external cache invalidate request
809                    if ( r_tgt_icache_req )     
810                    {
811                        r_icache_fsm = ICACHE_CC_CHECK;
812                        r_icache_fsm_save = r_icache_fsm.read();
813                        break;
814                    }
815                    // cleanup
816                    if(!r_icache_cleanup_req){
817                        r_icache_cleanup_req = true;
818                        r_icache_cleanup_line = r_icache_addr_save.read() >> (uint32_log2(m_icache_words) + 2);   
819                        r_icache_fsm = ICACHE_IDLE;
820                    }
821                    break;
822                }
823                /////////////////////
824            case ICACHE_CC_CHECK:   // read directory in case of invalidate or update request
825                {
826
827                    m_cpt_icache_dir_read += m_icache_ways;
828                    m_cpt_icache_data_read += m_icache_ways;
829                    addr_40  ad           = r_tgt_addr;
830                    data_t  icache_rdata = 0;
831
832                    if(( ( r_icache_fsm_save == ICACHE_MISS_WAIT ) || ( r_icache_fsm_save == ICACHE_MISS_UPDT ) ) &&
833                            ( (r_icache_addr_save.read() & ~((m_icache_words<<2)-1)) == (ad & ~((m_icache_words<<2)-1)))) {
834                        r_icache_inval_rsp = true;
835                        r_tgt_icache_req = false;
836                        if(r_tgt_update){    // Also send a cleanup and answer
837                            r_tgt_icache_rsp     = true;
838                        } else {            // Also send a cleanup but don't answer
839                            r_tgt_icache_rsp     = false;
840                        }
841                        r_icache_fsm = r_icache_fsm_save;
842                    } else {
843                        bool    icache_hit   = r_icache.read(ad, &icache_rdata);
844                        if ( icache_hit && r_tgt_update ) {
845                            r_icache_fsm = ICACHE_CC_UPDT;
846                            // complete the line buffer in case of update
847                            for(size_t i=0; i<m_icache_words; i++){
848                                data_t rdata = 0;
849                                r_icache.read(ad + i*4,&rdata);
850                                data_t mask = vci_param::be2mask(r_tgt_be[i]);
851                                r_tgt_buf[i] = (mask & r_tgt_buf[i]) | (~mask & rdata);
852                            }
853                        } else if ( icache_hit && !r_tgt_update ) {
854                            r_icache_fsm = ICACHE_CC_INVAL;
855                        } else { // instruction not found (can happen)
856                            r_tgt_icache_req = false;
857                            if(r_tgt_update){
858                                r_tgt_icache_rsp = true;
859                            } else {
860                                r_tgt_icache_rsp = false;
861                            }
862                            r_icache_fsm = r_icache_fsm_save;
863                        }
864                    }
865                    break;
866                }
867                /////////////////////
868            case ICACHE_CC_INVAL: 
869                {                       
870                    addr_40    ad  = r_tgt_addr;
871                    if ( ireq.valid ) m_cost_ins_miss_frz++;
872                    m_cpt_icache_dir_read += m_icache_ways;
873                    r_tgt_icache_rsp = true;
874                    r_icache.inval(ad);
875                    r_tgt_icache_req = false;
876                    r_icache_fsm = r_icache_fsm_save;
877                    break;
878                }   
879                /////////////////////
880            case ICACHE_CC_UPDT:
881                {                       
882                    m_cpt_icache_dir_write++;
883                    m_cpt_icache_data_write++;
884                    addr_40    ad  = r_tgt_addr.read();
885                    data_t* buf    = r_tgt_buf;
886                    for(size_t i=0; i<m_icache_words;i++){
887                        if(r_tgt_be[i]) r_icache.write( ad + i*4, buf[i]);
888                    }
889                    r_tgt_icache_req = false;
890                    r_tgt_icache_rsp = true;
891                    r_icache_fsm     = r_icache_fsm_save.read();
892                    break;
893                }   
894
895        } // end switch r_icache_fsm
896
897#if DEBUG_CC_XCACHE_WRAPPER
898        std::cout << " Instruction Response: " << irsp << std::endl;
899#endif
900
901        //////////////////////////////////////////////////////////////////////://///////////
902        // The DCACHE FSM controls the following ressources:
903        // - r_dcache_fsm
904        // - r_dcache_fsm_save
905        // - r_dcache (data cache access)
906        // - r_dcache_addr_save
907        // - r_dcache_wdata_save
908        // - r_dcache_rdata_save
909        // - r_dcache_type_save
910        // - r_dcache_be_save
911        // - r_dcache_cached_save
912        // - r_dcache_miss_req set
913        // - r_dcache_unc_req set
914        // - r_dcache_write_req set
915        // - r_dcache_cleanup_req set
916        // - r_vci_rsp_data_error reset
917        // - r_tgt_dcache_req reset
918        // - r_wbuf write
919        // - dreq & drsp structures for communication with the processor
920        //
921        // 1/ EXTERNAL REQUEST :
922        //    There is an external request when the tgt_dcache req flip-flop is set,
923        //    requesting a line invalidation or a line update.
924        //    External requests are taken into account in the states  IDLE, WRITE_REQ, 
925        //    UNC_WAIT, MISS_WAIT, and have the highest priority :
926        //    The actions associated to the pre-empted state are not executed, the DCACHE FSM
927        //    goes to the CC_CHECK state to execute the requested action, and returns to the
928        //    pre-empted state.
929        //  2/ PROCESSOR REQUEST :
930        //   In order to support VCI write burst, the processor requests are taken into account
931        //   in the WRITE_REQ state as well as in the IDLE state.
932        //   - In the IDLE state, the processor request cannot be satisfied if
933        //   there is a cached read miss, or an uncached read.
934        //   - In the WRITE_REQ state, the request cannot be satisfied if
935        //   there is a cached read miss, or an uncached read,
936        //   or when the write buffer is full.
937        //   - In all other states, the processor request is not satisfied.
938        //
939        //   The cache access takes into account the cacheability_table.
940        //   In case of processor request, there is five conditions to exit the IDLE state:
941        //   - CACHED READ MISS => to the MISS_WAIT state (waiting the r_miss_ok signal),
942        //     then to the MISS_UPDT state, and finally to the IDLE state.
943        //   - UNCACHED READ  => to the UNC_WAIT state (waiting the r_miss_ok signal),
944        //     and to the IDLE state.
945        //   - CACHE INVALIDATE HIT => to the INVAL state for one cycle, then to IDLE state.
946        //   - WRITE MISS => directly to the WRITE_REQ state to access the write buffer.
947        //   - WRITE HIT => to the WRITE_UPDT state, then to the WRITE_REQ state.
948        //
949        // Error handling :  Read Bus Errors are synchronous events, but
950        // Write Bus Errors are asynchronous events (processor is not frozen).
951        // - If a Read Bus Error is detected, the VCI_RSP FSM sets the
952        //   r_vci_rsp_data_error flip-flop, and the synchronous error is signaled
953        //   by the DCACHE FSM.
954        // - If a Write Bus Error is detected, the VCI_RSP FSM  signals
955        //   the asynchronous error using the setWriteBerr() method.
956        ///////////////////////////////////////////////////////////////////////////////////
957
958#if DEBUG_CC_XCACHE_WRAPPER
959        std::cout << " Data Request: " << dreq << std::endl;
960#endif
961
962        //if( (m_cpt_total_cycles % 10000) ==0 ) std::cout << std::dec << "Proc " << m_srcid << " Data Request: " << dreq << std::endl;
963
964        switch ( r_dcache_fsm ) {
965
966            /////////////////////
967            case DCACHE_WRITE_REQ:
968                {
969                    if ( r_tgt_dcache_req ) {   // external request
970                        r_dcache_fsm = DCACHE_CC_CHECK;
971                        r_dcache_fsm_save = r_dcache_fsm;
972                        break;
973                    }
974                    // try to post the write request in the write buffer
975                    if ( !r_dcache_write_req ) {    // no previous write transaction     
976                        if ( r_wbuf.wok(r_dcache_addr_save) ) {   // write request in the same cache line
977                            r_wbuf.write(r_dcache_addr_save, r_dcache_be_save, r_dcache_wdata_save);
978                            // close the write packet if uncached
979                            if ( !r_dcache_cached_save ){
980                                r_dcache_write_req = true ;
981                            }
982                        } else {   
983                            // close the write packet if write request not in the same cache line
984                            r_dcache_write_req = true; 
985                            if(!m_srcid_rw) {
986                            }
987                            m_cost_write_frz++;
988                            break;  // posting request not possible : stay in DCACHE_WRITEREQ state
989                        }
990                    } else {    //  previous write transaction not completed
991                        m_cost_write_frz++;
992                        break;  // posting request not possible : stay in DCACHE_WRITEREQ state 
993                    }
994
995                    // close the write packet if the next processor request is not a write
996                    if ( !dreq.valid || (dreq.type != iss_t::DATA_WRITE) ) {
997                        r_dcache_write_req = true ;
998                    }
999
1000                    // The next state and the processor request parameters are computed
1001                    // as in the DCACHE_IDLE state (see below ...)
1002                }
1003                /////////////////
1004            case DCACHE_IDLE:
1005                {
1006                    if ( r_tgt_dcache_req ) {   // external request
1007                        r_dcache_fsm = DCACHE_CC_CHECK;
1008                        r_dcache_fsm_save = r_dcache_fsm;
1009                        break;
1010                    }
1011
1012                    if ( dreq.valid ) {             
1013                        bool        dcache_hit     = false;
1014                        data_t      dcache_rdata   = 0;
1015                        bool        dcache_cached;
1016                        m_cpt_dcache_data_read += m_dcache_ways;
1017                        m_cpt_dcache_dir_read += m_dcache_ways;
1018
1019                        // dcache_cached evaluation
1020                        switch (dreq.type) {
1021                            case iss_t::DATA_SC:
1022                            case iss_t::XTN_READ:
1023                            case iss_t::XTN_WRITE:
1024                                dcache_cached = false;
1025                                break;
1026                            default:
1027                                dcache_cached = m_cacheability_table[(vci_addr_t)dreq.addr];
1028                        }
1029
1030                        // dcache_hit & dcache_rdata evaluation
1031                        if ( dcache_cached ) {
1032                            dcache_hit = r_dcache.read((vci_addr_t) dreq.addr, &dcache_rdata);
1033                        } else {
1034                            dcache_hit = false;
1035                        }
1036
1037                        switch( dreq.type ) {
1038                            case iss_t::DATA_READ:
1039                            case iss_t::DATA_LL:
1040                                m_cpt_read++;
1041                                if ( dcache_hit ) {
1042                                    r_dcache_fsm = DCACHE_IDLE;
1043                                    drsp.valid = true;
1044                                    drsp.rdata = dcache_rdata;
1045                                    if(dreq.type == iss_t::DATA_LL){
1046                                        r_dcache_ll_valid = true;
1047                                        r_dcache_ll_data = dcache_rdata;
1048                                        r_dcache_ll_addr = (vci_addr_t) dreq.addr;
1049#ifdef COHERENCE_DEBUG
1050                                        std::cout << "Value returned for LL at address : " << std::hex << dreq.addr << " data : " << std::dec << dcache_rdata<< std::endl;
1051                                        r_dcache.read((vci_addr_t) dreq.addr, &dcache_rdata);
1052                                        std::cout << "Value stored at this  address : " << std::hex << dreq.addr << " data : " << std::dec << dcache_rdata<< std::endl;
1053#endif
1054                                    }
1055                                } else {
1056                                    if ( dcache_cached ) {
1057                                        m_cpt_data_miss++;
1058                                        m_cost_data_miss_frz++;
1059                                        r_dcache_miss_req = true;
1060                                        r_dcache_fsm = DCACHE_MISS_WAIT;
1061                                    } else {
1062                                        m_cpt_unc_read++;
1063                                        m_cost_unc_read_frz++;
1064                                        r_dcache_unc_req = true;
1065                                        r_dcache_fsm = DCACHE_UNC_WAIT;
1066                                    }
1067                                }
1068                                break;
1069                            case iss_t::DATA_SC:
1070                            {
1071                                m_cpt_unc_read++;
1072                                m_cost_unc_read_frz++;
1073                                if(r_dcache_ll_valid.read() && (r_dcache_ll_addr.read() == (vci_addr_t)dreq.addr)){
1074                                    r_dcache_sc_req = true;
1075                                    r_dcache_fsm = DCACHE_SC_WAIT;
1076                                } else {
1077                                    drsp.valid = true;
1078                                    drsp.rdata = 1; // SC rsp NOK
1079                                    r_dcache_ll_valid = false;
1080                                }
1081                                break;
1082                            }
1083                            case iss_t::XTN_READ:
1084                            case iss_t::XTN_WRITE:
1085                                    // only DCACHE INVALIDATE request are supported
1086                                    if ( dreq.addr/4 == iss_t::XTN_DCACHE_INVAL ){
1087                                        r_dcache_fsm = DCACHE_INVAL;
1088                                    } else {
1089                                        r_dcache_fsm = DCACHE_IDLE;
1090                                    }
1091                                    drsp.valid = true;
1092                                    drsp.rdata = 0;
1093                                    break;
1094                            case iss_t::DATA_WRITE:
1095                                    m_cpt_write++;
1096                                    if ( dcache_hit && dcache_cached ) {
1097                                        r_dcache_fsm = DCACHE_WRITE_UPDT;
1098                                        m_cpt_write_cached++;
1099                                    } else {
1100                                        r_dcache_fsm = DCACHE_WRITE_REQ;
1101                                    }
1102                                    drsp.valid = true;
1103                                    drsp.rdata = 0;
1104                                    break;
1105                        } // end switch dreq.type
1106
1107                        r_dcache_addr_save      = (addr_40) dreq.addr;
1108                        r_dcache_type_save      = dreq.type;
1109                        r_dcache_wdata_save     = dreq.wdata;
1110                        r_dcache_be_save        = dreq.be;
1111                        r_dcache_rdata_save     = dcache_rdata;
1112                        r_dcache_cached_save    = dcache_cached;
1113
1114                    } else {    // end if dreq.valid
1115                        r_dcache_fsm = DCACHE_IDLE;
1116                    }
1117                    // processor request are not accepted in the WRITE_REQUEST state
1118                    // when the write buffer is not writeable
1119                    if ( (r_dcache_fsm == DCACHE_WRITE_REQ) &&
1120                            (r_dcache_write_req || !r_wbuf.wok(r_dcache_addr_save)) ) {
1121                        drsp.valid = false;
1122                        drsp.rdata = 0;
1123                    }
1124                    break;
1125                }
1126                ///////////////////////
1127            case DCACHE_WRITE_UPDT:
1128                {
1129                    m_cpt_dcache_data_write++;
1130                    data_t mask = vci_param::be2mask(r_dcache_be_save);
1131                    data_t wdata = (mask & r_dcache_wdata_save) | (~mask & r_dcache_rdata_save);
1132                    vci_addr_t ad = r_dcache_addr_save.read();
1133                    r_dcache.write(ad, wdata);
1134                    r_dcache_fsm = DCACHE_WRITE_REQ;
1135                    break;
1136                }
1137                //////////////////////
1138            case DCACHE_MISS_WAIT:
1139                {
1140
1141                    if ( dreq.valid ) m_cost_data_miss_frz++;
1142                    if ( r_tgt_dcache_req.read() ) {   // external request
1143                        r_dcache_fsm = DCACHE_CC_CHECK;
1144                        r_dcache_fsm_save = r_dcache_fsm;
1145                        break;
1146                    }
1147                    if ( !r_dcache_miss_req && !r_dcache_inval_rsp ) { // Miss read response and no invalidation
1148                        if ( r_vci_rsp_data_error ) {
1149                            r_dcache_fsm = DCACHE_ERROR;
1150                        } else {
1151                            r_dcache_fsm = DCACHE_MISS_UPDT;
1152                        }
1153                        break;
1154                    }
1155                    if ( !r_dcache_miss_req && r_dcache_inval_rsp ) { // Miss read response and invalidation
1156                        if ( r_vci_rsp_data_error ) {
1157                            r_dcache_inval_rsp  = false;
1158                            r_dcache_fsm = DCACHE_ERROR;
1159                        } else {
1160                            r_dcache_inval_rsp  = false;
1161                            r_dcache_fsm = DCACHE_CC_CLEANUP;
1162                        }
1163                        break;
1164                    }
1165                    break;
1166                }
1167                //////////////////////
1168            case DCACHE_MISS_UPDT:
1169
1170                {
1171                        if ( r_tgt_dcache_req.read() ) {   // external request
1172                        r_dcache_fsm = DCACHE_CC_CHECK;
1173                        r_dcache_fsm_save = r_dcache_fsm;
1174                        break;
1175                    }
1176                    if( !r_dcache_cleanup_req.read() && !r_dcache_inval_rsp ){
1177                        vci_addr_t  ad  = 0;
1178                        ad = (vci_addr_t) r_dcache_addr_save.read();
1179                        data_t* buf = new data_t[m_dcache_words];
1180                        for(size_t i=0; i<m_dcache_words; i++) {
1181                            buf[i] = r_dcache_miss_buf[i];
1182                        }
1183                        vci_addr_t  victim_index = 0;
1184                        if ( dreq.valid ) m_cost_data_miss_frz++;
1185                        m_cpt_dcache_data_write++;
1186                        m_cpt_dcache_dir_write++;
1187
1188                        r_dcache_cleanup_req = r_dcache.update(ad, buf, &victim_index);
1189                        r_dcache_cleanup_line = (addr_40) victim_index;
1190
1191                        r_dcache_fsm = DCACHE_IDLE;
1192                        delete [] buf;
1193                        break;
1194                    }
1195                    if( r_dcache_inval_rsp ){
1196                        r_dcache_inval_rsp  = false;
1197                        r_dcache_fsm = DCACHE_CC_CLEANUP;
1198                        break;
1199                    }
1200                    break;
1201                }
1202                ////////////////////
1203            case DCACHE_UNC_WAIT:
1204                {
1205                    if ( dreq.valid ) m_cost_unc_read_frz++;
1206                    if ( r_tgt_dcache_req ) {   // external request
1207                        r_dcache_fsm = DCACHE_CC_CHECK;
1208                        r_dcache_fsm_save = r_dcache_fsm;
1209                        break;
1210                    }
1211                    if ( !r_dcache_unc_req ) {
1212                        if ( r_vci_rsp_data_error ) {
1213                            r_dcache_fsm = DCACHE_ERROR;
1214                        } else {
1215                            if(dreq.type == iss_t::DATA_LL){
1216                                r_dcache_ll_valid = true;
1217                                r_dcache_ll_data = r_dcache_miss_buf[0];
1218                                r_dcache_ll_addr = (vci_addr_t) dreq.addr;
1219                            }
1220                            r_dcache_fsm = DCACHE_IDLE;
1221                            drsp.valid = true;
1222                            drsp.rdata = r_dcache_miss_buf[0];
1223                        }
1224                    }
1225                    break;
1226                }
1227                ////////////////////
1228            case DCACHE_SC_WAIT:
1229                {
1230                    if ( dreq.valid ) m_cost_unc_read_frz++;
1231                    if ( r_tgt_dcache_req ) {   // external request
1232                        r_dcache_fsm = DCACHE_CC_CHECK;
1233                        r_dcache_fsm_save = r_dcache_fsm;
1234                        break;
1235                    }
1236                    if ( !r_dcache_sc_req ) {
1237                        if ( r_vci_rsp_data_error ) {
1238                            r_dcache_fsm = DCACHE_ERROR;
1239                        } else {
1240                            r_dcache_fsm = DCACHE_IDLE;
1241                            drsp.valid = true;
1242                            drsp.rdata = r_dcache_miss_buf[0];
1243                            r_dcache_ll_valid = false;
1244                        }
1245                    }
1246                    break;
1247                }
1248
1249                //////////////////
1250            case DCACHE_ERROR:
1251                {
1252                    r_dcache_fsm = DCACHE_IDLE;
1253                    r_vci_rsp_data_error = false;
1254                    drsp.error = true;
1255                    drsp.valid = true;
1256                    break;
1257                }
1258                /////////////////   
1259            case DCACHE_INVAL:
1260                {
1261                    if ( r_tgt_dcache_req.read() ) {   // external request
1262                        r_dcache_fsm = DCACHE_CC_CHECK;
1263                        r_dcache_fsm_save = r_dcache_fsm;
1264                        break;
1265                    }
1266                    if( !r_dcache_cleanup_req.read() ){
1267                        m_cpt_dcache_dir_read += m_dcache_ways;
1268                        vci_addr_t  ad  = r_dcache_addr_save.read();
1269                        r_dcache_cleanup_req = r_dcache.inval(ad);
1270                        r_dcache_cleanup_line = r_dcache_addr_save.read() >> (uint32_log2(m_dcache_words)+2);
1271
1272                        r_dcache_fsm = DCACHE_IDLE;
1273                    }
1274                    break;
1275                }
1276                /////////////////////
1277            case DCACHE_CC_CHECK:   // read directory in case of invalidate or update request
1278                {
1279
1280                    m_cpt_dcache_dir_read += m_dcache_ways;
1281                    m_cpt_dcache_data_read += m_dcache_ways;
1282                    addr_40  ad           = r_tgt_addr;
1283                    data_t  dcache_rdata = 0;
1284
1285                    if(( ( r_dcache_fsm_save == DCACHE_MISS_WAIT ) || ( r_dcache_fsm_save == DCACHE_MISS_UPDT ) ) &&
1286                            ( (r_dcache_addr_save.read() & ~((m_dcache_words<<2)-1)) == (ad & ~((m_dcache_words<<2)-1)))) {
1287                        r_dcache_inval_rsp = true;
1288                        r_tgt_dcache_req = false;
1289                        if(r_tgt_update){    // Also send a cleanup and answer
1290                            r_tgt_dcache_rsp     = true;
1291                        } else {            // Also send a cleanup but don't answer
1292                            r_tgt_dcache_rsp     = false;
1293                        }
1294                        r_dcache_fsm = r_dcache_fsm_save;
1295                    } else {
1296                        bool    dcache_hit   = r_dcache.read(ad, &dcache_rdata);
1297#ifdef COHERENCE_DEBUG
1298                        std::cout << "PROC " << m_srcid_rw << " DCACHE_CC_CHECK, hit ? : " << dcache_hit << std::endl;
1299#endif
1300                        if ( dcache_hit && r_tgt_update ) {
1301                            // complete the line buffer in case of update
1302                            for(size_t i=0; i<m_dcache_words; i++){
1303                                data_t rdata = 0;
1304                                r_dcache.read(ad + i*4,&rdata);
1305                                data_t mask = vci_param::be2mask(r_tgt_be[i]);
1306                                r_tgt_buf[i] = (mask & r_tgt_buf[i]) | (~mask & rdata);
1307                            }
1308                            r_dcache_fsm = DCACHE_CC_UPDT;
1309                        } else if ( dcache_hit && !r_tgt_update ) {
1310                            r_dcache_fsm = DCACHE_CC_INVAL;
1311                        } else {
1312                            if(r_tgt_update){
1313                                r_tgt_dcache_rsp = true;
1314                            } else {
1315                                r_tgt_dcache_rsp = false;
1316                            }
1317                            r_tgt_dcache_req = false;
1318                            r_dcache_fsm = r_dcache_fsm_save;
1319                        }
1320                    }
1321                    break;
1322                }
1323                ///////////////////
1324            case DCACHE_CC_UPDT:    // update directory and data cache       
1325                {
1326                    m_cpt_dcache_dir_write++;
1327                    m_cpt_dcache_data_write++;
1328                    addr_40  ad      = r_tgt_addr;
1329                    data_t* buf     = r_tgt_buf;
1330#ifdef COHERENCE_DEBUG
1331                    std::cout << "PROC " << m_srcid_rw << " DCACHE_CC_UPDT, update : " << std::endl;
1332#endif
1333                    for(size_t i=0; i<m_dcache_words; i++){
1334                        if(r_tgt_be[i]) {
1335                            r_dcache.write( ad + i*4, buf[i]);
1336#ifdef COHERENCE_DEBUG
1337                            std::cout << " address " << std::hex << ad+i*4 << " data " << std::dec << buf[i] << std::endl;
1338                            data_t rdata = 0xAAAAAAAA;
1339                            r_dcache.read(ad + i*4,&rdata);
1340                            std::cout << "data written " << rdata << std::endl;
1341#endif
1342                        }
1343                    }
1344                    r_tgt_dcache_req = false;
1345                    r_tgt_dcache_rsp = true;
1346                    r_dcache_fsm = r_dcache_fsm_save;
1347                    break;
1348                }
1349                /////////////////////
1350            case DCACHE_CC_INVAL:   // invalidate a cache line
1351                {
1352                    addr_40  ad      = r_tgt_addr;
1353                    r_tgt_dcache_rsp = true;
1354                    r_dcache.inval(ad);
1355                    r_tgt_dcache_req = false;
1356                    r_dcache_fsm = r_dcache_fsm_save;
1357                    break;
1358                }
1359                ///////////////////
1360            case DCACHE_CC_CLEANUP:   
1361                {
1362                    // external cache invalidate request
1363                    if ( r_tgt_dcache_req )   
1364                    {
1365                        r_dcache_fsm = DCACHE_CC_CHECK;
1366                        r_dcache_fsm_save = r_dcache_fsm;
1367                        break;
1368                    }       
1369                    // cleanup
1370                    if(!r_dcache_cleanup_req){
1371                        r_dcache_cleanup_req = true;
1372                        r_dcache_cleanup_line = r_dcache_addr_save.read() >> (uint32_log2(m_dcache_words) + 2);
1373                        r_dcache_fsm = DCACHE_IDLE;
1374                    }
1375                    break;
1376                }   
1377
1378        } // end switch r_dcache_fsm
1379
1380#if DEBUG_CC_XCACHE_WRAPPER
1381        std::cout << " Data Response: " << drsp << std::endl;
1382#endif
1383
1384        /////////// execute one iss cycle /////////////////////////////////////////////
1385        {
1386            uint32_t it = 0;
1387            for (size_t i=0; i<(size_t)iss_t::n_irq; i++)
1388                if(p_irq[i].read()) it |= (1<<i);
1389            m_iss.executeNCycles(1, irsp, drsp, it);
1390        }
1391
1392        if ( (ireq.valid && !irsp.valid) || (dreq.valid && !drsp.valid) ) m_cpt_frz_cycles++;
1393
1394
1395        ////////////////////////////////////////////////////////////////////////////
1396        // The VCI_CMD FSM controls the following ressources:
1397        // - r_vci_cmd_fsm
1398        // - r_vci_cmd_min
1399        // - r_vci_cmd_max
1400        // - r_vci_cmd_cpt
1401        // - wbuf reset
1402        //
1403        // This FSM handles requests from both the DCACHE FSM & the ICACHE FSM.
1404        // There is 7 request types, with the following priorities :
1405        // 1 - Instruction Miss     : r_icache_miss_req
1406        // 2 - Data Write           : r_dcache_write_req
1407        // 3 - Data Read Miss       : r_dcache_miss_req
1408        // 4 - Data Read Uncached   : r_dcache_unc_req
1409        // 5 - Instruction Cleanup  : r_icache_cleanup_req
1410        // 6 - Data Cleanup         : r_dcache_cleanup_req
1411        // There is at most one (CMD/RSP) VCI transaction, as both CMD_FSM
1412        // and RSP_FSM exit simultaneously the IDLE state.
1413        //
1414        // VCI formats:
1415        // According to the VCI advanced specification, all read requests packets
1416        // (read Uncached, Miss data, Miss instruction) are one word packets.
1417        // For write burst packets, all words must be in the same cache line,
1418        // and addresses must be contiguous (the BE field is 0 in case of "holes").
1419        //////////////////////////////////////////////////////////////////////////////
1420
1421        switch (r_vci_cmd_fsm) {
1422
1423            case CMD_IDLE:
1424                if (r_vci_rsp_fsm != RSP_IDLE) break;
1425
1426                r_vci_cmd_cpt = 0;
1427                if ( r_icache_cleanup_req ) {
1428                    r_vci_cmd_fsm = CMD_INS_CLEANUP;
1429                } else if ( r_dcache_cleanup_req ) {
1430                    r_vci_cmd_fsm = CMD_DATA_CLEANUP;
1431                } else if ( r_icache_miss_req ) {
1432                    r_vci_cmd_fsm = CMD_INS_MISS;
1433                    m_cpt_imiss_transaction++;
1434                } else if ( r_icache_unc_req ) {
1435                    r_vci_cmd_fsm = CMD_INS_UNC;
1436                    m_cpt_imiss_transaction++;
1437                } else if ( r_dcache_write_req ) {
1438                    r_vci_cmd_fsm = CMD_DATA_WRITE;
1439                    r_vci_cmd_cpt = r_wbuf.getMin();
1440                    r_vci_cmd_min = r_wbuf.getMin();
1441                    r_vci_cmd_max = r_wbuf.getMax();
1442                    m_cpt_write_transaction++;
1443                    m_length_write_transaction += (r_wbuf.getMax() - r_wbuf.getMin() + 1);
1444                } else if ( r_dcache_miss_req ) {
1445                    r_vci_cmd_fsm = CMD_DATA_MISS;
1446                    m_cpt_dmiss_transaction++;
1447                } else if ( r_dcache_unc_req ) {
1448                    r_vci_cmd_fsm = CMD_DATA_UNC;
1449                    m_cpt_unc_transaction++;
1450                } else if ( r_dcache_sc_req ) {
1451                    r_vci_cmd_fsm = CMD_DATA_SC;
1452                    r_vci_cmd_max = 1;
1453                    m_cpt_unc_transaction++;
1454                }
1455                break;
1456
1457            case CMD_DATA_WRITE:
1458                if ( p_vci_ini_rw.cmdack.read() ) {
1459                    r_vci_cmd_cpt = r_vci_cmd_cpt + 1;
1460                    if (r_vci_cmd_cpt == r_vci_cmd_max) {
1461                        r_vci_cmd_fsm = CMD_IDLE ;
1462                        r_wbuf.reset() ;
1463                    }
1464                }
1465                break;
1466
1467            case CMD_DATA_SC:
1468                if ( p_vci_ini_rw.cmdack.read() ) {
1469                    r_vci_cmd_cpt = r_vci_cmd_cpt + 1;
1470                    if (r_vci_cmd_cpt == r_vci_cmd_max) {
1471                        r_vci_cmd_fsm = CMD_IDLE ;
1472                    }
1473                }
1474                break;
1475            case CMD_INS_MISS:
1476            case CMD_INS_UNC:
1477            case CMD_DATA_MISS:
1478            case CMD_DATA_UNC:
1479                if ( p_vci_ini_rw.cmdack.read() ) {
1480                    r_vci_cmd_fsm = CMD_IDLE;
1481                }
1482                break;
1483            case CMD_INS_CLEANUP:
1484            case CMD_DATA_CLEANUP:
1485                if ( p_vci_ini_c.cmdack.read() ) {
1486                    r_vci_cmd_fsm = CMD_IDLE;
1487                }
1488                break;
1489
1490        } // end  switch r_vci_cmd_fsm
1491
1492        //////////////////////////////////////////////////////////////////////////
1493        // The VCI_RSP FSM controls the following ressources:
1494        // - r_vci_rsp_fsm:
1495        // - r_icache_miss_buf[m_icache_words]
1496        // - r_dcache_miss_buf[m_dcache_words]
1497        // - r_icache_miss_req reset
1498        // - r_icache_unc_req reset
1499        // - r_dcache_miss_req reset
1500        // - r_icache_cleanup_req reset
1501        // - r_dcache_cleanup_req reset
1502        // - r_vci_rsp_data_error set
1503        // - r_vci_rsp_ins_error set
1504        // - r_vci_rsp_cpt
1505        // In order to have only one active VCI transaction, this VCI_RSP_FSM
1506        // is synchronized with the VCI_CMD FSM, and both FSMs exit the
1507        // IDLE state simultaneously.
1508        //
1509        // VCI formats:
1510        // This component accepts single word or multi-word response packets for
1511        // write response packets.
1512        //
1513        // Error handling:
1514        // This FSM analyzes the VCI error code and signals directly the
1515        // Write Bus Error.
1516        // In case of Read Data Error, the VCI_RSP FSM sets the r_vci_rsp_data_error
1517        // flip_flop and the error is signaled by the DCACHE FSM. 
1518        // In case of Instruction Error, the VCI_RSP FSM sets the r_vci_rsp_ins_error
1519        // flip_flop and the error is signaled by the DCACHE FSM. 
1520        // In case of Cleanup Error, the simulation stops with an error message...
1521        //////////////////////////////////////////////////////////////////////////
1522
1523        switch (r_vci_rsp_fsm) {
1524
1525            case RSP_IDLE:
1526                if(p_vci_ini_rw.rspval.read()||
1527                        p_vci_ini_c.rspval.read())
1528                {
1529                    std::cout << "CC_XCache " << m_srcid_rw << " Unexpected response" << std::endl;
1530                }
1531                assert( ! p_vci_ini_rw.rspval.read() && ! p_vci_ini_c.rspval.read() && "Unexpected response" );
1532                if (r_vci_cmd_fsm != CMD_IDLE) break;
1533
1534                r_vci_rsp_cpt = 0;
1535                if      ( r_icache_cleanup_req )    r_vci_rsp_fsm = RSP_INS_CLEANUP;
1536                else if ( r_dcache_cleanup_req )    r_vci_rsp_fsm = RSP_DATA_CLEANUP;
1537                else if ( r_icache_miss_req )       r_vci_rsp_fsm = RSP_INS_MISS;
1538                else if ( r_icache_unc_req )        r_vci_rsp_fsm = RSP_INS_UNC;
1539                else if ( r_dcache_write_req )      r_vci_rsp_fsm = RSP_DATA_WRITE;
1540                else if ( r_dcache_miss_req )       r_vci_rsp_fsm = RSP_DATA_MISS;
1541                else if ( r_dcache_unc_req )        r_vci_rsp_fsm = RSP_DATA_UNC;
1542                else if ( r_dcache_sc_req )         r_vci_rsp_fsm = RSP_DATA_SC;
1543                break;
1544
1545            case RSP_INS_MISS:
1546                m_cost_imiss_transaction++;
1547                if ( ! p_vci_ini_rw.rspval.read() )
1548                    break;
1549                assert( (r_vci_rsp_cpt < m_icache_words) &&
1550                        "The VCI response packet for instruction miss is too long" );
1551                r_vci_rsp_cpt = r_vci_rsp_cpt + 1;
1552                r_icache_miss_buf[r_vci_rsp_cpt] = (data_t)p_vci_ini_rw.rdata.read();
1553
1554                if ( p_vci_ini_rw.reop.read() ) {
1555                    assert( (r_vci_rsp_cpt == m_icache_words - 1) &&
1556                            "The VCI response packet for instruction miss is too short");
1557                    r_icache_miss_req = false;
1558                    r_vci_rsp_fsm = RSP_IDLE;
1559                }
1560                if ( (p_vci_ini_rw.rerror.read()&0x1) != vci_param::ERR_NORMAL ) r_vci_rsp_ins_error = true;
1561                break;
1562
1563            case RSP_INS_UNC:
1564                m_cost_imiss_transaction++;
1565                if ( ! p_vci_ini_rw.rspval.read() )
1566                    break;
1567                assert(p_vci_ini_rw.reop.read() &&
1568                        "illegal VCI response packet for uncached instruction");
1569                r_icache_miss_buf[0] = (data_t)p_vci_ini_rw.rdata.read();
1570                r_vci_rsp_fsm = RSP_IDLE;
1571                r_icache_unc_req = false;
1572                if ( (p_vci_ini_rw.rerror.read()&0x1) != vci_param::ERR_NORMAL ) r_vci_rsp_ins_error = true;
1573                break;
1574
1575            case RSP_DATA_MISS:
1576                m_cost_dmiss_transaction++;
1577                if ( ! p_vci_ini_rw.rspval.read() )
1578                    break;
1579                assert(r_vci_rsp_cpt != m_dcache_words &&
1580                        "illegal VCI response packet for data read miss");
1581                r_vci_rsp_cpt = r_vci_rsp_cpt + 1;
1582                r_dcache_miss_buf[r_vci_rsp_cpt] = (data_t)p_vci_ini_rw.rdata.read();
1583                if ( p_vci_ini_rw.reop.read() ) {
1584                    assert(r_vci_rsp_cpt == m_dcache_words - 1 &&
1585                            "illegal VCI response packet for data read miss");
1586                    r_dcache_miss_req = false;
1587                    r_vci_rsp_fsm = RSP_IDLE;
1588                }
1589                if ( (p_vci_ini_rw.rerror.read()&0x1) != vci_param::ERR_NORMAL ) r_vci_rsp_data_error = true;
1590                break;
1591
1592            case RSP_DATA_WRITE:
1593                m_cost_write_transaction++;
1594                if ( ! p_vci_ini_rw.rspval.read() )
1595                    break;
1596                if ( p_vci_ini_rw.reop.read() ) {
1597                    r_vci_rsp_fsm = RSP_IDLE;
1598                    r_dcache_write_req = false;
1599                }
1600                if ( (p_vci_ini_rw.rerror.read()&0x1) != vci_param::ERR_NORMAL ) m_iss.setWriteBerr();
1601                break;
1602
1603            case RSP_DATA_UNC:
1604                m_cost_unc_transaction++;
1605                if ( ! p_vci_ini_rw.rspval.read() )
1606                    break;
1607                assert(p_vci_ini_rw.reop.read() &&
1608                        "illegal VCI response packet for data read uncached");
1609                r_dcache_miss_buf[0] = (data_t)p_vci_ini_rw.rdata.read();
1610                r_vci_rsp_fsm = RSP_IDLE;
1611                r_dcache_unc_req = false;
1612                if ( (p_vci_ini_rw.rerror.read()&0x1) != vci_param::ERR_NORMAL ) r_vci_rsp_data_error = true;
1613                break;
1614
1615            case RSP_DATA_SC:
1616                m_cost_unc_transaction++;
1617                if ( ! p_vci_ini_rw.rspval.read() )
1618                    break;
1619                assert(p_vci_ini_rw.reop.read() &&
1620                        "illegal VCI response packet for data SC");
1621                r_dcache_miss_buf[0] = (data_t)p_vci_ini_rw.rdata.read();
1622                r_vci_rsp_fsm = RSP_IDLE;
1623                r_dcache_sc_req = false;
1624                if ( (p_vci_ini_rw.rerror.read()&0x1) != vci_param::ERR_NORMAL ) r_vci_rsp_data_error = true;
1625                break;
1626
1627            case RSP_INS_CLEANUP:
1628            case RSP_DATA_CLEANUP:
1629                if ( ! p_vci_ini_c.rspval.read() )
1630                    break;
1631                assert( p_vci_ini_c.reop.read() &&
1632                        "illegal VCI response packet for icache cleanup");
1633                assert( ((p_vci_ini_c.rerror.read()&0x1) == vci_param::ERR_NORMAL) &&
1634                        "error in response packet for icache cleanup");
1635                if ( r_vci_rsp_fsm == RSP_INS_CLEANUP ) r_icache_cleanup_req = false;
1636                else                                    r_dcache_cleanup_req = false;
1637                r_vci_rsp_fsm = RSP_IDLE;
1638                break;
1639
1640        } // end switch r_vci_rsp_fsm
1641
1642    } // end transition()
1643
1644    //////////////////////////////////////////////////////////////////////////////////
1645    tmpl(void)::genMoore()
1646        //////////////////////////////////////////////////////////////////////////////////
1647    {
1648        // VCI initiator response
1649
1650        p_vci_ini_rw.rspack = true;
1651        p_vci_ini_c.rspack = true;
1652
1653        // VCI initiator command
1654
1655        switch (r_vci_cmd_fsm.read() ) {
1656
1657            case CMD_IDLE:
1658                p_vci_ini_rw.cmdval  = false;
1659                p_vci_ini_rw.address = 0;
1660                p_vci_ini_rw.wdata   = 0;
1661                p_vci_ini_rw.be      = 0;
1662                p_vci_ini_rw.plen    = 0;
1663                p_vci_ini_rw.cmd     = vci_param::CMD_NOP;
1664                p_vci_ini_rw.trdid   = 0;
1665                p_vci_ini_rw.pktid   = 0;
1666                p_vci_ini_rw.srcid   = 0;
1667                p_vci_ini_rw.cons    = false;
1668                p_vci_ini_rw.wrap    = false;
1669                p_vci_ini_rw.contig  = false;
1670                p_vci_ini_rw.clen    = 0;
1671                p_vci_ini_rw.cfixed  = false;
1672                p_vci_ini_rw.eop     = false;
1673
1674                p_vci_ini_c.cmdval  = false;
1675                p_vci_ini_c.address = 0;
1676                p_vci_ini_c.wdata  = 0;
1677                p_vci_ini_c.be     = 0;
1678                p_vci_ini_c.plen   = 0;
1679                p_vci_ini_c.cmd    = vci_param::CMD_NOP;
1680                p_vci_ini_c.trdid  = 0;
1681                p_vci_ini_c.pktid  = 0;
1682                p_vci_ini_c.srcid  = 0;
1683                p_vci_ini_c.cons   = false;
1684                p_vci_ini_c.wrap   = false;
1685                p_vci_ini_c.contig = false;
1686                p_vci_ini_c.clen   = 0;
1687                p_vci_ini_c.cfixed = false;
1688                p_vci_ini_c.eop = false;
1689
1690                break;
1691
1692            case CMD_DATA_UNC:
1693                p_vci_ini_rw.cmdval = true;
1694                p_vci_ini_rw.address = (addr_40) r_dcache_addr_save.read() & ~0x3;
1695                switch( r_dcache_type_save ) {
1696                    case iss_t::DATA_READ:
1697                        p_vci_ini_rw.wdata = 0;
1698                        p_vci_ini_rw.be  = r_dcache_be_save.read();
1699                        p_vci_ini_rw.cmd = vci_param::CMD_READ;
1700                        break;
1701                    case iss_t::DATA_LL:
1702                        p_vci_ini_rw.wdata = 0;
1703                        p_vci_ini_rw.be  = 0xF;
1704                        p_vci_ini_rw.cmd = vci_param::CMD_LOCKED_READ;
1705                        break;
1706                    default:
1707                        assert("this should not happen");
1708                }
1709                p_vci_ini_rw.plen = 4;
1710                p_vci_ini_rw.trdid  = 0;   // data cache uncached read
1711                p_vci_ini_rw.pktid  = 0;
1712                p_vci_ini_rw.srcid  = m_srcid_rw;
1713                p_vci_ini_rw.cons   = false;
1714                p_vci_ini_rw.wrap   = false;
1715                p_vci_ini_rw.contig = true;
1716                p_vci_ini_rw.clen   = 0;
1717                p_vci_ini_rw.cfixed = false;
1718                p_vci_ini_rw.eop    = true;
1719
1720                p_vci_ini_c.cmdval  = false;
1721                p_vci_ini_c.address = 0;
1722                p_vci_ini_c.wdata  = 0;
1723                p_vci_ini_c.be     = 0;
1724                p_vci_ini_c.plen   = 0;
1725                p_vci_ini_c.cmd    = vci_param::CMD_NOP;
1726                p_vci_ini_c.trdid  = 0;
1727                p_vci_ini_c.pktid  = 0;
1728                p_vci_ini_c.srcid  = 0;
1729                p_vci_ini_c.cons   = false;
1730                p_vci_ini_c.wrap   = false;
1731                p_vci_ini_c.contig = false;
1732                p_vci_ini_c.clen   = 0;
1733                p_vci_ini_c.cfixed = false;
1734                p_vci_ini_c.eop = false;
1735
1736                break;
1737
1738            case CMD_DATA_SC:
1739                p_vci_ini_rw.cmdval = true;
1740                p_vci_ini_rw.address = (addr_40) r_dcache_addr_save.read() & ~0x3;
1741                if(r_vci_cmd_max.read() == 3){
1742                    assert(false && "Not handled yet");
1743                } else { // r_vci_cmd_cpt == 1
1744                    switch(r_vci_cmd_cpt.read()){
1745                        case 0:
1746                            p_vci_ini_rw.wdata = (uint32_t)(r_dcache_ll_data.read() & 0xFFFFFFFF);
1747                            break;
1748                        case 1:
1749                            p_vci_ini_rw.wdata = r_dcache_wdata_save.read();
1750                            break;
1751                    }
1752                }
1753                p_vci_ini_rw.be     = 0xF;
1754                p_vci_ini_rw.cmd    = vci_param::CMD_STORE_COND;
1755                p_vci_ini_rw.plen   = 4*(r_vci_cmd_max.read()+1);
1756                p_vci_ini_rw.trdid  = 0;   // data cache uncached read
1757                p_vci_ini_rw.pktid  = 0;
1758                p_vci_ini_rw.srcid  = m_srcid_rw;
1759                p_vci_ini_rw.cons   = true;
1760                p_vci_ini_rw.wrap   = false;
1761                p_vci_ini_rw.contig = false;
1762                p_vci_ini_rw.clen   = 0;
1763                p_vci_ini_rw.cfixed = false;
1764                p_vci_ini_rw.eop    = (r_vci_cmd_cpt.read() == r_vci_cmd_max.read());
1765
1766                p_vci_ini_c.cmdval  = false;
1767                p_vci_ini_c.address = 0;
1768                p_vci_ini_c.wdata  = 0;
1769                p_vci_ini_c.be     = 0;
1770                p_vci_ini_c.plen   = 0;
1771                p_vci_ini_c.cmd    = vci_param::CMD_NOP;
1772                p_vci_ini_c.trdid  = 0;
1773                p_vci_ini_c.pktid  = 0;
1774                p_vci_ini_c.srcid  = 0;
1775                p_vci_ini_c.cons   = false;
1776                p_vci_ini_c.wrap   = false;
1777                p_vci_ini_c.contig = false;
1778                p_vci_ini_c.clen   = 0;
1779                p_vci_ini_c.cfixed = false;
1780                p_vci_ini_c.eop = false;
1781
1782                break;
1783
1784            case CMD_DATA_WRITE:
1785                p_vci_ini_rw.cmdval  = true;
1786                p_vci_ini_rw.address = r_wbuf.getAddress(r_vci_cmd_cpt)&~0x3;
1787                p_vci_ini_rw.wdata   = r_wbuf.getData(r_vci_cmd_cpt);
1788                p_vci_ini_rw.be      = r_wbuf.getBe(r_vci_cmd_cpt);
1789                p_vci_ini_rw.plen    = (r_vci_cmd_max - r_vci_cmd_min + 1)<<2;
1790                p_vci_ini_rw.cmd     = vci_param::CMD_WRITE;
1791                p_vci_ini_rw.trdid   = 0;  // data cache write
1792                p_vci_ini_rw.pktid   = 0;
1793                p_vci_ini_rw.srcid   = m_srcid_rw;
1794                p_vci_ini_rw.cons    = false;
1795                p_vci_ini_rw.wrap    = false;
1796                p_vci_ini_rw.contig  = true;
1797                p_vci_ini_rw.clen    = 0;
1798                p_vci_ini_rw.cfixed  = false;
1799                p_vci_ini_rw.eop     = (r_vci_cmd_cpt == r_vci_cmd_max);
1800
1801                p_vci_ini_c.cmdval  = false;
1802                p_vci_ini_c.address = 0;
1803                p_vci_ini_c.wdata  = 0;
1804                p_vci_ini_c.be     = 0;
1805                p_vci_ini_c.plen   = 0;
1806                p_vci_ini_c.cmd    = vci_param::CMD_NOP;
1807                p_vci_ini_c.trdid  = 0;
1808                p_vci_ini_c.pktid  = 0;
1809                p_vci_ini_c.srcid  = 0;
1810                p_vci_ini_c.cons   = false;
1811                p_vci_ini_c.wrap   = false;
1812                p_vci_ini_c.contig = false;
1813                p_vci_ini_c.clen   = 0;
1814                p_vci_ini_c.cfixed = false;
1815                p_vci_ini_c.eop = false;
1816
1817                break;
1818
1819            case CMD_DATA_MISS:
1820                p_vci_ini_rw.cmdval = true;
1821                p_vci_ini_rw.address = r_dcache_addr_save.read() & (addr_40) m_dcache_yzmask;
1822                p_vci_ini_rw.be     = 0xF;
1823                p_vci_ini_rw.plen   = m_dcache_words << 2;
1824                p_vci_ini_rw.cmd    = vci_param::CMD_READ;
1825                p_vci_ini_rw.trdid  = 1;   // data cache cached read
1826                p_vci_ini_rw.pktid  = 0;
1827                p_vci_ini_rw.srcid  = m_srcid_rw;
1828                p_vci_ini_rw.cons   = false;
1829                p_vci_ini_rw.wrap   = false;
1830                p_vci_ini_rw.contig = true;
1831                p_vci_ini_rw.clen   = 0;
1832                p_vci_ini_rw.cfixed = false;
1833                p_vci_ini_rw.eop = true;
1834
1835                p_vci_ini_c.cmdval  = false;
1836                p_vci_ini_c.address = 0;
1837                p_vci_ini_c.wdata  = 0;
1838                p_vci_ini_c.be     = 0;
1839                p_vci_ini_c.plen   = 0;
1840                p_vci_ini_c.cmd    = vci_param::CMD_NOP;
1841                p_vci_ini_c.trdid  = 0;
1842                p_vci_ini_c.pktid  = 0;
1843                p_vci_ini_c.srcid  = 0;
1844                p_vci_ini_c.cons   = false;
1845                p_vci_ini_c.wrap   = false;
1846                p_vci_ini_c.contig = false;
1847                p_vci_ini_c.clen   = 0;
1848                p_vci_ini_c.cfixed = false;
1849                p_vci_ini_c.eop = false;
1850
1851                break;
1852
1853            case CMD_INS_MISS:
1854                p_vci_ini_rw.cmdval = true;
1855                p_vci_ini_rw.address = r_icache_addr_save.read() & (addr_40) m_icache_yzmask;
1856                p_vci_ini_rw.be     = 0xF;
1857                p_vci_ini_rw.plen   = m_icache_words << 2;
1858                p_vci_ini_rw.cmd    = vci_param::CMD_READ;
1859                p_vci_ini_rw.trdid  = 3;   // ins cache cached read
1860                p_vci_ini_rw.pktid  = 0;
1861                p_vci_ini_rw.srcid  = m_srcid_rw;
1862                p_vci_ini_rw.cons   = false;
1863                p_vci_ini_rw.wrap   = false;
1864                p_vci_ini_rw.contig = true;
1865                p_vci_ini_rw.clen   = 0;
1866                p_vci_ini_rw.cfixed = false;
1867                p_vci_ini_rw.eop = true;
1868
1869                p_vci_ini_c.cmdval  = false;
1870                p_vci_ini_c.address = 0;
1871                p_vci_ini_c.wdata  = 0;
1872                p_vci_ini_c.be     = 0;
1873                p_vci_ini_c.plen   = 0;
1874                p_vci_ini_c.cmd    = vci_param::CMD_NOP;
1875                p_vci_ini_c.trdid  = 0;
1876                p_vci_ini_c.pktid  = 0;
1877                p_vci_ini_c.srcid  = 0;
1878                p_vci_ini_c.cons   = false;
1879                p_vci_ini_c.wrap   = false;
1880                p_vci_ini_c.contig = false;
1881                p_vci_ini_c.clen   = 0;
1882                p_vci_ini_c.cfixed = false;
1883                p_vci_ini_c.eop = false;
1884
1885                break;
1886
1887            case CMD_INS_UNC:
1888                p_vci_ini_rw.cmdval = true;
1889                p_vci_ini_rw.address = r_icache_addr_save.read() & ~0x3;
1890                p_vci_ini_rw.be     = 0xF;
1891                p_vci_ini_rw.plen   = 4;
1892                p_vci_ini_rw.cmd    = vci_param::CMD_READ;
1893                p_vci_ini_rw.trdid  = 2;   // ins cache uncached read
1894                p_vci_ini_rw.pktid  = 0;
1895                p_vci_ini_rw.srcid  = m_srcid_rw;
1896                p_vci_ini_rw.cons   = false;
1897                p_vci_ini_rw.wrap   = false;
1898                p_vci_ini_rw.contig = true;
1899                p_vci_ini_rw.clen   = 0;
1900                p_vci_ini_rw.cfixed = false;
1901                p_vci_ini_rw.eop = true;
1902
1903                p_vci_ini_c.cmdval  = false;
1904                p_vci_ini_c.address = 0;
1905                p_vci_ini_c.wdata  = 0;
1906                p_vci_ini_c.be     = 0;
1907                p_vci_ini_c.plen   = 0;
1908                p_vci_ini_c.cmd    = vci_param::CMD_NOP;
1909                p_vci_ini_c.trdid  = 0;
1910                p_vci_ini_c.pktid  = 0;
1911                p_vci_ini_c.srcid  = 0;
1912                p_vci_ini_c.cons   = false;
1913                p_vci_ini_c.wrap   = false;
1914                p_vci_ini_c.contig = false;
1915                p_vci_ini_c.clen   = 0;
1916                p_vci_ini_c.cfixed = false;
1917                p_vci_ini_c.eop = false;
1918
1919
1920                break;
1921
1922            case CMD_INS_CLEANUP:
1923                p_vci_ini_rw.cmdval = false;
1924                p_vci_ini_rw.address = 0;
1925                p_vci_ini_rw.wdata  = 0;
1926                p_vci_ini_rw.be     = 0;
1927                p_vci_ini_rw.plen   = 0;
1928                p_vci_ini_rw.cmd    = vci_param::CMD_NOP;
1929                p_vci_ini_rw.trdid  = 0;
1930                p_vci_ini_rw.pktid  = 0;
1931                p_vci_ini_rw.srcid  = 0;
1932                p_vci_ini_rw.cons   = false;
1933                p_vci_ini_rw.wrap   = false;
1934                p_vci_ini_rw.contig = false;
1935                p_vci_ini_rw.clen   = 0;
1936                p_vci_ini_rw.cfixed = false;
1937                p_vci_ini_rw.eop    = false;
1938
1939                p_vci_ini_c.cmdval  = true;
1940                p_vci_ini_c.address = r_icache_cleanup_line.read() * (m_icache_words<<2);
1941                p_vci_ini_c.wdata  = 0;
1942                p_vci_ini_c.be     = 0;
1943                p_vci_ini_c.plen   = 4;
1944                p_vci_ini_c.cmd    = vci_param::CMD_WRITE;
1945                p_vci_ini_c.trdid  = 1; // cleanup instruction
1946                p_vci_ini_c.pktid  = 0;
1947                p_vci_ini_c.srcid  = m_srcid_c;
1948                p_vci_ini_c.cons   = false;
1949                p_vci_ini_c.wrap   = false;
1950                p_vci_ini_c.contig = false;
1951                p_vci_ini_c.clen   = 0;
1952                p_vci_ini_c.cfixed = false;
1953                p_vci_ini_c.eop = true;
1954
1955                break;
1956
1957
1958            case CMD_DATA_CLEANUP:
1959                p_vci_ini_rw.cmdval = false;
1960                p_vci_ini_rw.address = 0;
1961                p_vci_ini_rw.wdata  = 0;
1962                p_vci_ini_rw.be     = 0;
1963                p_vci_ini_rw.plen   = 0;
1964                p_vci_ini_rw.cmd    = vci_param::CMD_NOP;
1965                p_vci_ini_rw.trdid  = 0;
1966                p_vci_ini_rw.pktid  = 0;
1967                p_vci_ini_rw.srcid  = 0;
1968                p_vci_ini_rw.cons   = false;
1969                p_vci_ini_rw.wrap   = false;
1970                p_vci_ini_rw.contig = false;
1971                p_vci_ini_rw.clen   = 0;
1972                p_vci_ini_rw.cfixed = false;
1973                p_vci_ini_rw.eop    = false;
1974
1975                p_vci_ini_c.cmdval  = true;
1976                p_vci_ini_c.address = r_dcache_cleanup_line.read() * (m_dcache_words<<2);
1977                p_vci_ini_c.wdata  = 0;
1978                p_vci_ini_c.be     = 0;
1979                p_vci_ini_c.plen   = 4;
1980                p_vci_ini_c.cmd    = vci_param::CMD_WRITE;
1981                p_vci_ini_c.trdid  = 0; // cleanup data
1982                p_vci_ini_c.pktid  = 0;
1983                p_vci_ini_c.srcid  = m_srcid_c;
1984                p_vci_ini_c.cons   = false;
1985                p_vci_ini_c.wrap   = false;
1986                p_vci_ini_c.contig = false;
1987                p_vci_ini_c.clen   = 0;
1988                p_vci_ini_c.cfixed = false;
1989                p_vci_ini_c.eop = true;
1990
1991                break;
1992
1993        } // end switch r_vci_cmd_fsm
1994
1995        // VCI_TGT
1996
1997        switch ( r_vci_tgt_fsm.read() ) {
1998
1999            case TGT_IDLE:
2000            case TGT_UPDT_WORD:
2001            case TGT_UPDT_DATA:
2002                p_vci_tgt.cmdack  = true;
2003                p_vci_tgt.rspval  = false;
2004                break;
2005
2006            case TGT_RSP_BROADCAST:
2007                p_vci_tgt.cmdack  = false;
2008                p_vci_tgt.rspval  = !r_tgt_icache_req.read() && !r_tgt_dcache_req.read() && ( r_tgt_icache_rsp | r_tgt_dcache_rsp );
2009                p_vci_tgt.rsrcid  = r_tgt_srcid.read();
2010                p_vci_tgt.rpktid  = r_tgt_pktid.read();
2011                p_vci_tgt.rtrdid  = r_tgt_trdid.read();
2012                p_vci_tgt.rdata   = 0;
2013                p_vci_tgt.rerror  = 0x2 & ( (1 << (vci_param::E + 1)) - 1); // Write OK
2014                p_vci_tgt.reop    = true;
2015                break;
2016
2017            case TGT_RSP_ICACHE:
2018                p_vci_tgt.cmdack  = false;
2019                p_vci_tgt.rspval  = !r_tgt_icache_req.read() && r_tgt_icache_rsp.read();
2020                p_vci_tgt.rsrcid  = r_tgt_srcid.read();
2021                p_vci_tgt.rpktid  = r_tgt_pktid.read();
2022                p_vci_tgt.rtrdid  = r_tgt_trdid.read();
2023                p_vci_tgt.rdata   = 0;
2024                p_vci_tgt.rerror  = 0x2 & ( (1 << (vci_param::E + 1)) - 1); // Write OK
2025                p_vci_tgt.reop    = true;
2026                break;
2027
2028            case TGT_RSP_DCACHE:
2029                p_vci_tgt.cmdack  = false;
2030                p_vci_tgt.rspval  = !r_tgt_dcache_req.read() && r_tgt_dcache_rsp.read();
2031                p_vci_tgt.rsrcid  = r_tgt_srcid.read();
2032                p_vci_tgt.rpktid  = r_tgt_pktid.read();
2033                p_vci_tgt.rtrdid  = r_tgt_trdid.read();
2034                p_vci_tgt.rdata   = 0;
2035                p_vci_tgt.rerror  = 0x2 & ( (1 << (vci_param::E + 1)) - 1); // Write OK
2036                p_vci_tgt.reop    = true;
2037                break;
2038
2039            case TGT_REQ_BROADCAST:
2040            case TGT_REQ_ICACHE:
2041            case TGT_REQ_DCACHE:
2042                p_vci_tgt.cmdack  = false;
2043                p_vci_tgt.rspval  = false;
2044                break;
2045
2046        } // end switch TGT_FSM
2047    } // end genMoore()
2048
2049}} // end namespace
2050
2051// Local Variables:
2052// tab-width: 4
2053// c-basic-offset: 4
2054// c-file-offsets:((innamespace . 0)(inline-open . 0))
2055// indent-tabs-mode: nil
2056// End:
2057
2058// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
2059
2060
2061
2062
Note: See TracBrowser for help on using the repository browser.