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

Last change on this file since 191 was 191, checked in by cfuguet, 12 years ago

Cleanup transaction modification

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