source: trunk/modules/vci_cc_xcache_wrapper_v1/caba/source/src/vci_cc_xcache_wrapper_v1.cpp @ 85

Last change on this file since 85 was 85, checked in by simerabe, 14 years ago

removing duplicate ring_signals_2

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