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

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

Don't check rsp length in case of error.
Check that the processor didn't change its mind before returning an error.

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