Changeset 45


Ignore:
Timestamp:
Jun 8, 2010, 5:04:20 PM (14 years ago)
Author:
alain
Message:

Introducing an improved memory consistency in the multi-write-buffer:

  • write after write and read after write policy for cachable access
  • fully blocking uncachable access (for both read and write requests)
Location:
trunk/modules/vci_cc_xcache_wrapper_multi/caba/source
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/modules/vci_cc_xcache_wrapper_multi/caba/source/include/vci_cc_xcache_wrapper_multi.h

    r2 r45  
    6565        DCACHE_MISS_UPDT,
    6666        DCACHE_UNC_WAIT,
     67        DCACHE_UNC_GO,
    6768        DCACHE_INVAL,
    6869        DCACHE_SYNC,
     
    8081        ICACHE_MISS_UPDT,
    8182        ICACHE_UNC_WAIT,
     83        ICACHE_UNC_GO,
    8284        ICACHE_ERROR,
    8385        ICACHE_CC_CHECK,
     
    117119
    118120    enum cleanup_fsm_state_e {
    119         CLEANUP_CMD,
    120         CLEANUP_DCACHE_RSP,
    121         CLEANUP_ICACHE_RSP,
     121        CLEANUP_IDLE,
     122        CLEANUP_DCACHE,
     123        CLEANUP_ICACHE,
    122124    };
    123125
     
    148150    const uint32_t                                                      m_srcid_c;   
    149151   
    150     const size_t                                m_wbuf_nlines;
    151152    const size_t                                                        m_dcache_ways;
    152153    const size_t                                                        m_dcache_words;
     
    233234    uint32_t m_cpt_icache_dir_write;        // ICACHE DIR WRITE
    234235
    235     uint32_t m_cpt_cc_update;               // number of coherence update packets
    236     uint32_t m_cpt_cc_inval;                // number of coherence inval packets
     236    uint32_t m_cpt_cc_broadcast;            // number of coherence broadcast packets
     237    uint32_t m_cpt_cc_update_data;          // number of coherence data update packets
     238    uint32_t m_cpt_cc_update_ins;           // number of coherence instruction update packets
     239    uint32_t m_cpt_cc_inval_data;           // number of coherence data inval packets
     240    uint32_t m_cpt_cc_inval_ins;            // number of coherence instruction inval packets
     241    uint32_t m_cpt_cc_cleanup_data;         // number of coherence data cleanup packets
     242    uint32_t m_cpt_cc_cleanup_ins;          // number of coherence instruction cleanup packets
    237243
    238244    uint32_t m_cpt_frz_cycles;              // number of cycles where the cpu is frozen
    239245    uint32_t m_cpt_total_cycles;            // total number of cycles
    240246
    241     uint32_t m_cpt_read;                    // total number of read instructions
    242     uint32_t m_cpt_write;                   // total number of write instructions
     247    uint32_t m_cpt_read;                    // total number of read requests
     248    uint32_t m_cpt_write;                   // total number of write requests
     249    uint32_t m_cpt_write_cached;            // number of cached write requests
     250    uint32_t m_cpt_data_unc;                // number of uncachable data requests
     251    uint32_t m_cpt_ins_unc;                 // number of uncachable instruction requests
     252    uint32_t m_cpt_ll;                      // number of ll requests
     253    uint32_t m_cpt_sc;                      // number of sc requests
    243254    uint32_t m_cpt_data_miss;               // number of read miss
    244255    uint32_t m_cpt_ins_miss;                // number of instruction miss
    245     uint32_t m_cpt_unc_read;                // number of read uncached
    246     uint32_t m_cpt_write_cached;            // number of cached write
    247256
    248257    uint32_t m_cost_write_frz;              // number of frozen cycles related to write buffer         
    249258    uint32_t m_cost_data_miss_frz;          // number of frozen cycles related to data miss
    250     uint32_t m_cost_unc_read_frz;           // number of frozen cycles related to uncached read
     259    uint32_t m_cost_unc_frz;                // number of frozen cycles related to uncached read
    251260    uint32_t m_cost_ins_miss_frz;           // number of frozen cycles related to ins miss
    252261
    253262    uint32_t m_cpt_imiss_transaction;       // number of VCI instruction miss transactions
    254263    uint32_t m_cpt_dmiss_transaction;       // number of VCI data miss transactions
    255     uint32_t m_cpt_unc_transaction;         // number of VCI uncached read transactions
     264    uint32_t m_cpt_data_unc_transaction;    // number of VCI instruction uncached transactions
     265    uint32_t m_cpt_ins_unc_transaction;     // number of VCI data uncached transactions
    256266    uint32_t m_cpt_write_transaction;       // number of VCI write transactions
    257267
     
    278288                       size_t dcache_words,
    279289                       size_t wbuf_nwords,
    280                        size_t wbuf_nlines );
     290                       size_t wbuf_nlines,
     291                       size_t wbuf_timeout);
    281292
    282293    ~VciCcXCacheWrapperMulti();
    283294
    284     void print_cpi();
    285     void print_stats();
     295    void printTrace(size_t mode);
     296    void printStatistics();
    286297
    287298private:
     
    290301    void genMoore();
    291302
    292     soclib_static_assert((int)iss_t::SC_ATOMIC == (int)vci_param::STORE_COND_ATOMIC);
    293     soclib_static_assert((int)iss_t::SC_NOT_ATOMIC == (int)vci_param::STORE_COND_NOT_ATOMIC);
     303    static_assert((int)iss_t::SC_ATOMIC == (int)vci_param::STORE_COND_ATOMIC);
     304    static_assert((int)iss_t::SC_NOT_ATOMIC == (int)vci_param::STORE_COND_NOT_ATOMIC);
    294305};
    295306
  • trunk/modules/vci_cc_xcache_wrapper_multi/caba/source/src/vci_cc_xcache_wrapper_multi.cpp

    r2 r45  
    5454//   WRITE_WORD requests in the same word, only the last request is conserved.
    5555//   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
     56//   the requests are merged in the same word. In case of uncachable write
    5757//   requests, each request is transmited as a single VCI transaction.
    5858//   Both the data & instruction caches can be flushed in one single cycle.
     
    6565//   introduced. The VCI command & response FSMs are not synchronized anymore:
    6666//   The read requests can be transmitted before previous write requests
    67 //   (if the missing address does not match apending write in the write buffer)
     67//   (if the missing address does not match a pending write in the write buffer)
    6868//   and several read & write requests can be simultaneously transmitted.
    6969//   The transactions can complete in any order, depending on the network.
     
    7676//   on the line index in the write buffer: PKTID = 2*wbuf_index + 1
    7777//   The transaction index has an even value for a read transaction, with only
    78 //   only four possible values, depending on cached/uncached & data/instruction.
     78//   only four possible values, depending on cachable/uncachable & data/instruction.
    7979//   A new CLEANUP FSM has been introduced to transmit the cleanups
    8080//   request from the DCACHE & ICACHE FSM on the coherence network.
    81 //   The LL/SC requests are still uncached.
     81//   The LL/SC requests are still uncachable.
     82// - 07/06/2010
     83//   The DCACHE FSM has been modified to enforce a well defined consistency model:
     84//   1) All uncachable acces (both read and write) are now blocking
     85//      the processor until the VCI response is received.
     86//      Uncachable access are considered as I/O access and must respect
     87//      a strict sequencial policy.
     88//   2) For cachable access, the write buffer supports the "read after write"
     89//      rule, and the "write after write" rule : registered write requests
     90//      are tested before handling a read miss, and before locking a buffer line.
     91//   The MultiWriteBuffer component has been modified, to support
     92//   these rules, and to have an associative behavior: it can exist several
     93//   open lines, with a private time-out for each open line.
     94//   A printTrace() method has been defined.
    8295///////////////////////////////////////////////////////////////////////////////
    83 
    84 //#define SOCLIB_MODULE_DEBUG 1
    8596
    8697#include <cassert>
     
    91102namespace caba {
    92103
    93 #if SOCLIB_MODULE_DEBUG
    94104    namespace {
    95105        const char *dcache_fsm_state_str[] = {
     
    102112            "DCACHE_MISS_UPDT   ",
    103113            "DCACHE_UNC_WAIT    ",
     114            "DCACHE_UNC_GO      ",
    104115            "DCACHE_INVAL       ",
    105116            "DCACHE_SYNC        ",
     
    116127            "ICACHE_MISS_UPDT   ",
    117128            "ICACHE_UNC_WAIT    ",
     129            "ICACHE_UNC_GO      ",
    118130            "ICACHE_ERROR       ",
    119131            "ICACHE_CC_CHECK    ",
     
    149161        };
    150162        const char *cleanup_fsm_state_str[] = {
    151             "CLEANUP_CMD",
    152             "CLEANUP_DCACHE_RSP",
    153             "CLEANUP_ICACHE_RSP",
     163            "CLEANUP_IDLE",
     164            "CLEANUP_DCACHE",
     165            "CLEANUP_ICACHE",
    154166        };
    155167    }
    156 #endif
    157168
    158169#define tmpl(...)  template<typename vci_param, typename iss_t> __VA_ARGS__ VciCcXCacheWrapperMulti<vci_param, iss_t>
     
    162173    /////////////////////////////////////
    163174    tmpl(/**/)::VciCcXCacheWrapperMulti(
    164     /////////////////////////////////////
    165175            sc_module_name name,
    166176            int proc_id,
     
    177187            size_t dcache_words,
    178188            size_t wbuf_nwords,
    179             size_t wbuf_nlines )
     189            size_t wbuf_nlines,
     190            size_t wbuf_timeout)
    180191        :
    181192            soclib::caba::BaseModule(name),
     
    199210            m_icache_words(icache_words),
    200211            m_icache_yzmask((~0)<<(uint32_log2(icache_words) + 2)),
    201             m_wbuf_nlines(wbuf_nlines),
    202212
    203213            r_dcache_fsm("r_dcache_fsm"),
     
    253263            r_cleanup_fsm("r_cleanup_fsm"),
    254264
    255             r_wbuf("r_wbuf", wbuf_nwords, wbuf_nlines),
     265            r_wbuf("r_wbuf", wbuf_nwords, wbuf_nlines, wbuf_timeout),
    256266            r_icache("icache", icache_ways, icache_sets, icache_words),
    257267            r_dcache("dcache", dcache_ways, dcache_sets, dcache_words)
    258268
    259269            {
    260 
    261                 assert( (m_wbuf_nlines== 1 || m_wbuf_nlines == 2 || m_wbuf_nlines == 4 || m_wbuf_nlines == 8 || m_wbuf_nlines == 16) &&
    262                       "number of lines must be power of 2, no larger than 16");
     270                assert( (icache_words*vci_param::B) < (1<<vci_param::K) &&
     271                        "I need more PLEN bits");
     272
     273                assert( (vci_param::T > 2) && ((1<<(vci_param::T-1)) >= wbuf_nlines) &&
     274                        "I need more TRDID bits");
    263275
    264276                r_icache_miss_buf = new data_t[icache_words];
     
    289301    //////////////////////////////////////
    290302    tmpl(/**/)::~VciCcXCacheWrapperMulti()
    291     //////////////////////////////////////
    292303    {
    293304        delete [] r_icache_miss_buf;
     
    297308    }
    298309
    299     ////////////////////////
    300     tmpl(void)::print_cpi()
    301     ////////////////////////
     310    ///////////////////////////////////
     311    tmpl(void)::printTrace(size_t mode)
    302312    {
    303         std::cout << "CPU " << m_srcid_d << " : CPI = "
    304             << (float)m_cpt_total_cycles/(m_cpt_total_cycles - m_cpt_frz_cycles) << std::endl ;
     313        typename iss_t::InstructionRequest  ireq;
     314        typename iss_t::DataRequest         dreq;
     315
     316        m_iss.getRequests( ireq, dreq );
     317        std::cout << std::dec << "Proc " << m_srcid_d << std::endl;
     318        std::cout << ireq << std::endl;
     319        std::cout << dreq << std::endl;
     320        std::cout << "  " << dcache_fsm_state_str[r_dcache_fsm]
     321                  << "  " << icache_fsm_state_str[r_icache_fsm]
     322                  << "  " << cmd_fsm_state_str[r_cmd_fsm]
     323                  << "  " << rsp_fsm_state_str[r_rsp_fsm]
     324                  << "  " << tgt_fsm_state_str[r_tgt_fsm]
     325                  << "  " << cleanup_fsm_state_str[r_cleanup_fsm] << std::endl;
     326        if(mode & 0x1)
     327        {
     328            r_wbuf.printTrace();
     329        }
     330        if(mode & 0x2)
     331        {
     332            std::cout << "  Data cache" << std::endl;
     333            r_dcache.printTrace();
     334        }
     335        if(mode & 0x4)
     336        {
     337            std::cout << "  Instruction cache" << std::endl;
     338            r_icache.printTrace();
     339        }
    305340    }
    306     ////////////////////////
    307     tmpl(void)::print_stats()
    308         ////////////////////////
     341    /////////////////////////////
     342    tmpl(void)::printStatistics()
    309343    {
    310344        float run_cycles = (float)(m_cpt_total_cycles - m_cpt_frz_cycles);
    311345        std::cout << "------------------------------------" << std:: dec << std::endl
    312         << "CPU " << m_srcid_d << " / Time = " << m_cpt_total_cycles << std::endl
     346        << "CPU " << m_srcid_d << " / cycles = " << m_cpt_total_cycles << std::endl
    313347        << "- CPI               = " << (float)m_cpt_total_cycles/run_cycles << std::endl
    314348        << "- READ RATE         = " << (float)m_cpt_read/run_cycles << std::endl
    315         << "- UNC READ RATE     = " << (float)m_cpt_unc_read/m_cpt_read << std::endl
    316349        << "- WRITE RATE        = " << (float)m_cpt_write/run_cycles << std::endl
    317350        << "- CACHED WRITE RATE = " << (float)m_cpt_write_cached/m_cpt_write << std::endl
     351        << "- UNC RATE          = " << (float)m_cpt_data_unc/run_cycles << std::endl
     352        << "- LL RATE           = " << (float)m_cpt_ll/run_cycles << std::endl
     353        << "- SC RATE           = " << (float)m_cpt_sc/run_cycles << std::endl
    318354        << "- IMISS_RATE        = " << (float)m_cpt_ins_miss/run_cycles << std::endl
    319355        << "- IMISS COST        = " << (float)m_cost_ins_miss_frz/m_cpt_ins_miss << std::endl
    320         << "- DMISS RATE        = " << (float)m_cpt_data_miss/(m_cpt_read-m_cpt_unc_read) << std::endl
     356        << "- DMISS RATE        = " << (float)m_cpt_data_miss/m_cpt_read << std::endl
    321357        << "- DMISS COST        = " << (float)m_cost_data_miss_frz/m_cpt_data_miss << std::endl
    322         << "- UNC COST          = " << (float)m_cost_unc_read_frz/m_cpt_unc_read << std::endl
     358        << "- UNC COST          = " << (float)m_cost_unc_frz/m_cpt_data_unc << std::endl
    323359        << "- WRITE COST        = " << (float)m_cost_write_frz/m_cpt_write << std::endl
    324         << "- WRITE LENGTH      = " << (float)m_length_write_transaction/m_cpt_write_transaction
    325         << std::endl;
     360        << "- WRITE LENGTH      = " << (float)m_length_write_transaction/m_cpt_write_transaction << std::endl
     361        << "- CC_BROADCAST      = " << m_cpt_cc_broadcast << std::endl
     362        << "- CC_UPDATE_DATA    = " << m_cpt_cc_update_data << std::endl
     363        << "- CC_UPDATE_INS     = " << m_cpt_cc_update_ins << std::endl
     364        << "- CC_INVAL_DATA     = " << m_cpt_cc_inval_data << std::endl
     365        << "- CC_INVAL_INS      = " << m_cpt_cc_inval_ins << std::endl
     366        << "- CC_CLEANUP_DATA   = " << m_cpt_cc_cleanup_data << std::endl
     367        << "- CC_CLEANUP_INS    = " << m_cpt_cc_cleanup_ins << std::endl;
    326368    }
    327369
    328370    //////////////////////////
    329371    tmpl(void)::transition()
    330     //////////////////////////
    331372    {
    332373        if ( ! p_resetn.read() ) {
     
    340381            r_rsp_fsm           = RSP_IDLE;
    341382            r_tgt_fsm           = TGT_IDLE;
    342             r_cleanup_fsm       = CLEANUP_CMD;
     383            r_cleanup_fsm       = CLEANUP_IDLE;
    343384
    344385            // write buffer & caches
     
    378419            m_cpt_dcache_dir_read  = 0;
    379420            m_cpt_dcache_dir_write = 0;
     421
    380422            m_cpt_icache_data_read  = 0;
    381423            m_cpt_icache_data_write = 0;
     
    383425            m_cpt_icache_dir_write = 0;
    384426
    385             m_cpt_cc_update = 0;
    386             m_cpt_cc_inval = 0;
     427            m_cpt_cc_broadcast = 0;
     428            m_cpt_cc_update_data = 0;
     429            m_cpt_cc_inval_data = 0;
     430            m_cpt_cc_cleanup_data = 0;
     431            m_cpt_cc_update_ins = 0;
     432            m_cpt_cc_inval_ins = 0;
     433            m_cpt_cc_cleanup_ins = 0;
    387434
    388435            m_cpt_frz_cycles = 0;
     
    391438            m_cpt_read = 0;
    392439            m_cpt_write = 0;
     440            m_cpt_write_cached = 0;
     441            m_cpt_data_unc = 0;
     442            m_cpt_ins_unc = 0;
     443            m_cpt_ll = 0;
     444            m_cpt_sc = 0;
    393445            m_cpt_data_miss = 0;
    394446            m_cpt_ins_miss = 0;
    395             m_cpt_unc_read = 0;
    396             m_cpt_write_cached = 0;
    397447
    398448            m_cost_write_frz = 0;
    399449            m_cost_data_miss_frz = 0;
    400             m_cost_unc_read_frz = 0;
     450            m_cost_unc_frz = 0;
    401451            m_cost_ins_miss_frz = 0;
    402452
    403453            m_cpt_imiss_transaction = 0;
    404454            m_cpt_dmiss_transaction = 0;
    405             m_cpt_unc_transaction = 0;
     455            m_cpt_data_unc_transaction = 0;
     456            m_cpt_ins_unc_transaction = 0;
    406457            m_cpt_write_transaction = 0;
    407458
     
    412463if ( m_srcid_d == 0 )
    413464{
    414 std::cout << "--------------------------------------------" << std::endl
    415           << std::dec << "CACHE " << m_srcid_d << " / Time = " << m_cpt_total_cycles << std::endl
     465std::cout << std::dec << "CcXcache " << m_srcid_d << " / Time = " << m_cpt_total_cycles << std::endl
    416466          << "  " << dcache_fsm_state_str[r_dcache_fsm]
    417467          << "  " << icache_fsm_state_str[r_icache_fsm]
     
    420470          << "  " << cleanup_fsm_state_str[r_cleanup_fsm]
    421471          << "  " << tgt_fsm_state_str[r_tgt_fsm] << std::endl;
    422 r_wbuf.print();
    423472}
    424473#endif
     
    499548                        r_tgt_brdcast= true;
    500549                        r_tgt_fsm = TGT_REQ_BROADCAST;
    501                         m_cpt_cc_inval++ ;
     550                        m_cpt_cc_broadcast++;
    502551                    }
    503552                    else                    // multicast-update or multicast-invalidate
     
    516565                            r_tgt_data    = true;
    517566                            r_tgt_fsm = TGT_REQ_DCACHE;
    518                             m_cpt_cc_inval++ ;
     567                            m_cpt_cc_inval_data++;
    519568                        }
    520569                        else if (cell == 4)             // update data
     
    530579                            r_tgt_data     = true;
    531580                            r_tgt_fsm  = TGT_UPDT_WORD;
    532                             m_cpt_cc_update++ ;
     581                            m_cpt_cc_update_data++;
    533582                        }
    534583                        else if (cell == 8)              // invalidate instruction
     
    544593                            r_tgt_update  = false;
    545594                            r_tgt_fsm = TGT_REQ_ICACHE;
    546                             m_cpt_cc_inval++ ;
     595                            m_cpt_cc_inval_ins++;
    547596                        }
    548597                        else if (cell == 12)             // update ins
     
    558607                            r_tgt_data    = false;
    559608                            r_tgt_fsm = TGT_UPDT_WORD;
    560                             m_cpt_cc_update++ ;
     609                            m_cpt_cc_update_ins++;
    561610                        }
    562611
     
    680729        } // end switch TGT_FSM
    681730
     731        typename iss_t::InstructionRequest      ireq;
     732        typename iss_t::InstructionResponse     irsp;
     733
     734        typename iss_t::DataRequest             dreq;
     735        typename iss_t::DataResponse            drsp;
     736
     737        ireq.valid = false;
     738        dreq.valid = false;
     739        irsp.valid = false;
     740        irsp.error = false;
     741        drsp.valid = false;
     742        drsp.error = false;
     743
     744        m_iss.getRequests( ireq, dreq );
     745
    682746        //////////////////////////////////////////////////////////////////////////////
    683747        // The ICACHE FSM controls the following ressources:
    684748        // - r_icache_fsm
    685749        // - r_icache_fsm_save
    686         // - r_icache instruction cache access
     750        // - r_icache (read & write)
    687751        // - r_icache_addr_save
    688         // - r_icache_miss_req set
    689         // - r_icache_unc_req set
    690         // - r_rsp_ins_ok reset
    691         // - r_rsp_ins_error reset
    692         // - r_tgt_icache_req reset
     752        // - r_icache_miss_req (set)
     753        // - r_icache_unc_req (set)
     754        // - r_rsp_ins_ok (reset)
     755        // - r_rsp_ins_error (reset)
     756        // - r_tgt_icache_req (reset)
    693757        // - r_tgt_icache_rsp
    694         // - r_icache_cleanup_req set
    695         // - r_icache_cleanup_ine
    696         // - ireq & irsp structures for communication with the processor
     758        // - r_icache_cleanup_req (set)
     759        // - r_icache_cleanup_line
     760        // - ireq & irsp structures (communication with the processor)
    697761        //
    698         // 1/ External requests (update or invalidate)
     762        // 1/ External coherence requests (update or invalidate)
    699763        //    There is an external request when the r_tgt_icache_req flip-flop is set,
    700764        //    These requests are taken into account in the IDLE and WAIT states.
     
    704768        //
    705769        // 2/ Processor requests are taken into account only in the IDLE state.
    706         //    In case of MISS, or in case of uncached instruction, the FSM
     770        //    The cache access takes into account the cacheability_table.
     771        //    In case of MISS, or in case of uncachable instruction, the FSM
    707772        //    writes the missing address line in the  r_icache_addr_save register
    708773        //    and sets the r_icache_miss_req or the r_icache_unc_req flip-flops.
     
    719784        ////////////////////////////////////////////////////////////////////////////////////
    720785
    721         typename iss_t::InstructionRequest  ireq = ISS_IREQ_INITIALIZER;
    722         typename iss_t::InstructionResponse irsp = ISS_IRSP_INITIALIZER;
    723 
    724         typename iss_t::DataRequest  dreq = ISS_DREQ_INITIALIZER;
    725         typename iss_t::DataResponse drsp = ISS_DRSP_INITIALIZER;
    726 
    727         m_iss.getRequests( ireq, dreq );
    728 
    729786        switch(r_icache_fsm) {
    730787 
    731             case ICACHE_IDLE:
    732             {
    733                 if ( r_tgt_icache_req )    // external request
    734                 {
    735                     if ( ireq.valid ) m_cost_ins_miss_frz++;
    736                     r_icache_fsm = ICACHE_CC_CHECK;
    737                     r_icache_fsm_save = r_icache_fsm;
    738                     break;
    739                 }
    740                 if ( ireq.valid )
    741                 {
    742                     data_t  icache_ins = 0;
    743                     bool    icache_hit = false;
    744                     bool    icache_cached = m_cacheability_table[(addr_t)ireq.addr];
    745                     // icache_hit & icache_ins evaluation
    746                     if ( icache_cached )
    747                     {
    748                         icache_hit = r_icache.read((addr_t)ireq.addr, &icache_ins);
    749                     }
    750                     else
    751                     {
    752                         icache_hit = (r_rsp_ins_ok && ( (addr_t)ireq.addr == (addr_t)r_icache_addr_save));
    753                         icache_ins = r_icache_miss_buf[0];
    754                     }
    755                     if ( ! icache_hit )  // miss
     788        case ICACHE_IDLE:
     789        {
     790            if ( r_tgt_icache_req )    // external request
     791            {
     792                if ( ireq.valid ) m_cost_ins_miss_frz++;
     793                r_icache_fsm = ICACHE_CC_CHECK;
     794                r_icache_fsm_save = r_icache_fsm;
     795                break;
     796            }
     797            if ( ireq.valid )
     798            {
     799                data_t  icache_ins;
     800                bool    icache_cachable = m_cacheability_table[(addr_t)ireq.addr];
     801                m_cpt_icache_dir_read += m_icache_ways;
     802                m_cpt_icache_data_read += m_icache_ways;
     803                if ( icache_cachable )
     804                {
     805                    if ( r_icache.read((addr_t)ireq.addr, &icache_ins) )        // hit
     806                    {
     807                        r_icache_fsm        = ICACHE_IDLE;
     808                        irsp.valid          = true;
     809                        irsp.instruction    = icache_ins;
     810                    }
     811                    else                                                        // miss
    756812                    {
    757813                        m_cpt_ins_miss++;
    758814                        m_cost_ins_miss_frz++;
    759                         r_icache_addr_save = (addr_t)ireq.addr;
    760                         if ( icache_cached )    // cached line
    761                         {
    762                             // if the missing line corresponds to a pending cleanup
    763                             // the miss request to the CMD FSM must be delayed
    764                             if ( r_icache_cleanup_req &&
    765                                ((addr_t)r_icache_cleanup_line == (addr_t)(ireq.addr/(m_icache_words*4))) )
    766                             {
    767                                 break;
    768                             }
    769                             else
    770                             {
    771                                 r_icache_fsm            = ICACHE_MISS_SELECT;
    772                                 r_icache_miss_req       = true;
    773                                 r_rsp_ins_ok            = false;
    774                             }
    775                         }
    776                         else                    // uncached line
    777                         {
    778                             r_icache_fsm        = ICACHE_UNC_WAIT;
    779                             r_icache_unc_req    = true;
    780                             r_rsp_ins_ok        = false;
    781                         }
    782                     }
    783                     else  // hit : the uncached data should not be re-used
    784                     {
    785                         r_rsp_ins_ok = false;
    786                     }
    787                     m_cpt_icache_dir_read += m_icache_ways;
    788                     m_cpt_icache_data_read += m_icache_ways;
    789                     irsp.valid          = icache_hit;
    790                     irsp.instruction    = icache_ins;
    791                 } // end if ireq.valid
    792                 break;
    793             }
    794             case ICACHE_MISS_SELECT:
    795             {
    796                 m_cost_ins_miss_frz++;
    797                 size_t  way;
    798                 addr_t  index;
    799                 addr_t  ad = r_icache_addr_save;
    800                 if ( r_icache.select_before_update( ad, &way, &index) )
    801                 {
    802                     r_icache_fsm          = ICACHE_MISS_CLEANUP;
    803                     r_icache_cleanup_save = index;
    804                     r_icache_way_save     = way;
    805                 }
    806                 else
    807                 {
    808                     r_icache_way_save     = way;
    809                     r_icache_fsm          = ICACHE_MISS_WAIT;
    810                 }
    811                 break;
    812             }
    813             case ICACHE_MISS_CLEANUP: // try to post a cleanup request to the CLEANUP FSM
    814             {
    815                 m_cost_ins_miss_frz++;
    816                 if ( r_tgt_icache_req )    // coherence request
    817                 {
    818                     r_icache_fsm = ICACHE_CC_CHECK;
    819                     r_icache_fsm_save = r_icache_fsm;
    820                     break;
    821                 }
    822                 if ( !r_icache_cleanup_req )    // no pending cleanup
    823                 {
    824                     r_icache_cleanup_req        = true;
    825                     r_icache_cleanup_line   = r_icache_cleanup_save.read();
    826                     r_icache_fsm                = ICACHE_MISS_WAIT;
    827                 }
    828                 break;               
    829             }
    830             case ICACHE_MISS_WAIT:  // waiting the response from the RSP FSM
    831             {
    832                 m_cost_ins_miss_frz++;
    833                 if ( r_tgt_icache_req )    // coherence request
    834                 {
    835                     r_icache_fsm = ICACHE_CC_CHECK;
    836                     r_icache_fsm_save = r_icache_fsm;
    837                     break;
    838                 }
    839                 if ( r_rsp_ins_ok )  // there is a response
    840                 {
    841                     if      ( r_rsp_ins_error )         r_icache_fsm = ICACHE_ERROR;
    842                     else if ( !r_icache_inval_pending ) r_icache_fsm = ICACHE_MISS_UPDT;
    843                     else
    844                     {
    845                         if ( r_icache_cleanup_req )
     815                        // if the missing line corresponds to a pending cleanup
     816                        // the miss request to the CMD FSM must be delayed
     817                        if ( r_icache_cleanup_req &&
     818                           ((addr_t)r_icache_cleanup_line == (addr_t)(ireq.addr/(m_icache_words*4))) )
    846819                        {
    847820                            break;
     
    849822                        else
    850823                        {
    851                             r_icache_cleanup_req = true;
    852                             r_icache_cleanup_line = r_icache_addr_save.read() >> (uint32_log2(m_icache_words) + 2);
    853                             r_icache_fsm = ICACHE_IDLE;
    854                             r_icache_inval_pending = false;
     824                            r_icache_fsm        = ICACHE_MISS_SELECT;
     825                            r_icache_addr_save  = ireq.addr;
     826                            r_icache_miss_req   = true;
     827                            r_rsp_ins_ok        = false;
    855828                        }
    856829                    }
    857830                }
    858                 break;
    859             }
    860             case ICACHE_MISS_UPDT:  // update the cache
    861             {
    862                 m_cost_ins_miss_frz++;
    863                 m_cpt_icache_dir_write++;
    864                 m_cpt_icache_data_write++;
    865                 addr_t          ad      = (addr_t) r_icache_addr_save;
    866                 data_t*         buf     = (data_t*) r_icache_miss_buf;
    867                 size_t          way     = (size_t) r_icache_way_save;
    868                 r_icache.update_after_select( buf, way, ad );
    869                 r_icache_fsm = ICACHE_IDLE;
    870                 break;
    871             }
    872             case ICACHE_UNC_WAIT:
    873             {
    874                 m_cost_ins_miss_frz++;
    875                 if ( r_tgt_icache_req )    // external request
    876                 {
    877                     r_icache_fsm = ICACHE_CC_CHECK;
    878                     r_icache_fsm_save = r_icache_fsm;
    879                     break;
     831                else                        // uncachable instruction
     832                {
     833                    m_cpt_ins_unc++;
     834                    m_cost_ins_miss_frz++;
     835                    r_icache_addr_save      = ireq.addr;
     836                    r_icache_fsm            = ICACHE_UNC_WAIT;
     837                    r_icache_unc_req        = true;
     838                    r_rsp_ins_ok            = false;
     839                }
     840            }
     841            break;
     842        }
     843        case ICACHE_MISS_SELECT: // select a victim
     844        {
     845            m_cost_ins_miss_frz++;
     846            size_t      way;
     847            addr_t      index;
     848            addr_t  ad = r_icache_addr_save;
     849            if ( r_icache.select_before_update( ad, &way, &index) )
     850            {
     851                r_icache_fsm          = ICACHE_MISS_CLEANUP;
     852                r_icache_cleanup_save = index;
     853                r_icache_way_save     = way;
     854            }
     855            else
     856            {
     857                r_icache_way_save     = way;
     858                r_icache_fsm          = ICACHE_MISS_WAIT;
     859            }
     860            break;
     861        }
     862        case ICACHE_MISS_CLEANUP: // try to post a cleanup request to the CLEANUP FSM
     863        {
     864            m_cost_ins_miss_frz++;
     865            if ( r_tgt_icache_req )    // coherence request
     866            {
     867                r_icache_fsm = ICACHE_CC_CHECK;
     868                r_icache_fsm_save = r_icache_fsm;
     869                break;
     870            }
     871            if ( !r_icache_cleanup_req )        // no pending cleanup
     872            {
     873                r_icache_cleanup_req    = true;
     874                r_icache_cleanup_line   = r_icache_cleanup_save;
     875                r_icache_fsm            = ICACHE_MISS_WAIT;
     876            }
     877            break;               
     878        }
     879        case ICACHE_MISS_WAIT:  // waiting the response from the RSP FSM
     880        {
     881            m_cost_ins_miss_frz++;
     882            if ( r_tgt_icache_req )    // coherence request
     883            {
     884                r_icache_fsm = ICACHE_CC_CHECK;
     885                r_icache_fsm_save = r_icache_fsm;
     886                break;
     887            }
     888            if ( r_rsp_ins_ok )  // there is a response
     889            {
     890                if      ( r_rsp_ins_error )             r_icache_fsm = ICACHE_ERROR;
     891                else if ( !r_icache_inval_pending )     r_icache_fsm = ICACHE_MISS_UPDT;
     892                else
     893                {
     894                    if ( r_icache_cleanup_req )
     895                    {
     896                        break;
     897                    }
     898                    else
     899                    {
     900                        // the cache is not updated in case of pending inval
     901                        r_icache_cleanup_req = true;
     902                        r_icache_cleanup_line = r_icache_addr_save.read() >> (uint32_log2(m_icache_words) + 2);
     903                        r_icache_fsm = ICACHE_IDLE;
     904                        r_icache_inval_pending = false;
     905                    }
     906                }
     907            }
     908            break;
     909        }
     910        case ICACHE_MISS_UPDT:  // update the cache
     911        {
     912            m_cost_ins_miss_frz++;
     913            m_cpt_icache_dir_write++;
     914            m_cpt_icache_data_write++;
     915            addr_t      ad      = (addr_t) r_icache_addr_save;
     916            data_t*     buf     = (data_t*) r_icache_miss_buf;
     917            size_t      way     = (size_t) r_icache_way_save;
     918            r_icache.update_after_select( buf, way, ad );
     919            r_icache_fsm = ICACHE_IDLE;
     920            break;
     921        }
     922        case ICACHE_UNC_WAIT:
     923        {
     924            m_cost_ins_miss_frz++;
     925            if ( r_tgt_icache_req )    // external request
     926            {
     927                r_icache_fsm = ICACHE_CC_CHECK;
     928                r_icache_fsm_save = r_icache_fsm;
     929                break;
     930            }
     931            if ( r_rsp_ins_ok )
     932            {
     933                if ( r_rsp_ins_error )  r_icache_fsm = ICACHE_ERROR;
     934                else                    r_icache_fsm = ICACHE_UNC_GO;
     935            }
     936            break;
     937        }
     938        case ICACHE_UNC_GO:
     939        {
     940            r_icache_fsm    = ICACHE_IDLE;
     941            if( ireq.addr == r_icache_addr_save )
     942            {
     943                irsp.valid          = true;
     944                irsp.instruction    = r_icache_miss_buf[0];
     945            }
     946        }
     947        case ICACHE_ERROR:
     948        {
     949            r_icache_fsm        = ICACHE_IDLE;
     950            r_rsp_ins_error     = false;
     951            irsp.error          = true;
     952            irsp.valid          = true;
     953            break;
     954        }
     955        case ICACHE_CC_CHECK:   // read directory in case of external request
     956        {
     957            m_cpt_icache_dir_read += m_icache_ways;
     958            m_cpt_icache_data_read += m_icache_ways;
     959            if ( ( (r_icache_fsm_save == ICACHE_MISS_WAIT) || (r_icache_fsm_save == ICACHE_MISS_CLEANUP) ) &&
     960                ((r_icache_addr_save & ~((m_icache_words<<2)-1))==(r_tgt_addr & ~((m_icache_words<<2)-1))))
     961                 // the external request matches a miss
     962            {
     963                r_icache_inval_pending  = true;
     964                r_tgt_icache_req        = false;
     965                r_tgt_icache_rsp        = r_tgt_update;  // always a response in case of update
     966                r_icache_fsm            = r_icache_fsm_save;
     967            }
     968            else  // the external request is not matching a pending miss
     969            {
     970                data_t  data;
     971                bool    icache_hit      = r_icache.read(r_tgt_addr, &data);
     972                if ( icache_hit && r_tgt_update )  // hit update
     973                {
     974                    r_icache_fsm = ICACHE_CC_UPDT;
    880975                }
    881                 if ( r_rsp_ins_ok )
    882                 {
    883                     if ( r_rsp_ins_error )      r_icache_fsm = ICACHE_ERROR;
    884                     else                        r_icache_fsm = ICACHE_IDLE;
    885                 }
    886                 break;
    887             }
    888             case ICACHE_ERROR:
    889             {
    890                 r_icache_fsm = ICACHE_IDLE;
    891                 r_rsp_ins_error     = false;
    892                 irsp.error          = true;
    893                 irsp.valid          = true;
    894                 break;
    895             }
    896             case ICACHE_CC_CHECK:   // read directory in case of external request
    897             {
    898                 m_cpt_icache_dir_read += m_icache_ways;
    899                 m_cpt_icache_data_read += m_icache_ways;
    900                 if ( ( (r_icache_fsm_save == ICACHE_MISS_WAIT) || (r_icache_fsm_save == ICACHE_MISS_CLEANUP) ) && // external request matches a miss
    901                 ((r_icache_addr_save & ~((m_icache_words<<2)-1))==(r_tgt_addr & ~((m_icache_words<<2)-1))))
    902                 {
    903                     r_icache_inval_pending      = true;
    904                     r_tgt_icache_req            = false;
    905                     r_tgt_icache_rsp            = r_tgt_update;  // always a response n case of update
    906                     r_icache_fsm                = r_icache_fsm_save;
     976                else if ( icache_hit && !r_tgt_update ) // hit inval
     977                {
     978                    r_icache_fsm = ICACHE_CC_INVAL;
    907979                }
    908                 else  // the external request is not matching a pending miss
    909                 {
    910                     data_t  data;
    911                     bool    icache_hit          = r_icache.read(r_tgt_addr, &data);
    912                     if ( icache_hit && r_tgt_update )  // hit update
    913                     {
    914                         r_icache_fsm = ICACHE_CC_UPDT;
    915                     }
    916                     else if ( icache_hit && !r_tgt_update ) // hit inval
    917                     {
    918                         r_icache_fsm = ICACHE_CC_INVAL;
    919                     }
    920                     else        // miss
    921                     {
    922                         r_tgt_icache_req        = false;
    923                         r_tgt_icache_rsp        = r_tgt_update; // alaways a response in case of update
    924                         r_icache_fsm            = r_icache_fsm_save;
    925                     }
    926                 }
    927                 break;
    928             }
    929             case ICACHE_CC_UPDT:    // update the cache line       
    930             {
    931                 m_cpt_icache_dir_write++;
    932                 m_cpt_icache_data_write++;
    933                 for(size_t i=0; i<m_icache_words; i++)
    934                 {
    935                     if(r_tgt_val[i]) r_icache.write( (r_tgt_addr + i*4), r_tgt_buf[i] );
    936                 }
    937                 r_tgt_icache_rsp = true;
    938                 r_tgt_icache_req = false;
    939                 r_icache_fsm = r_icache_fsm_save;
    940                 break;
    941             }
    942             case ICACHE_CC_INVAL:   // invalidate a cache line
    943             {
    944                 r_icache.inval(r_tgt_addr);
    945                 r_tgt_icache_rsp = true;
    946                 r_tgt_icache_req = false;
    947                 r_icache_fsm = r_icache_fsm_save;
    948                 break;
    949             }
     980                else    // miss
     981                {
     982                    r_tgt_icache_req    = false;
     983                    r_tgt_icache_rsp    = r_tgt_update; // alaways a response in case of update
     984                    r_icache_fsm        = r_icache_fsm_save;
     985                }
     986            }
     987            break;
     988        }
     989        case ICACHE_CC_UPDT:    // update the cache line       
     990        {
     991            m_cpt_icache_dir_write++;
     992            m_cpt_icache_data_write++;
     993            for(size_t i=0; i<m_icache_words; i++)
     994            {
     995                if(r_tgt_val[i]) r_icache.write( (r_tgt_addr + i*4), r_tgt_buf[i] );
     996            }
     997            r_tgt_icache_rsp = true;
     998            r_tgt_icache_req = false;
     999            r_icache_fsm = r_icache_fsm_save;
     1000            break;
     1001        }
     1002        case ICACHE_CC_INVAL:   // invalidate a cache line
     1003        {
     1004            r_icache.inval(r_tgt_addr);
     1005            r_tgt_icache_rsp = true;
     1006            r_tgt_icache_req = false;
     1007            r_icache_fsm = r_icache_fsm_save;
     1008            break;
     1009        }
    9501010        } // end switch r_icache_fsm
    9511011
     
    9541014        // - r_dcache_fsm
    9551015        // - r_dcache_fsm_save
    956         // - r_dcache (data cache access)
     1016        // - r_dcache (read and write)
    9571017        // - r_dcache_addr_save
    9581018        // - r_dcache_wdata_save
     
    9601020        // - r_dcache_type_save
    9611021        // - r_dcache_be_save
    962         // - r_dcache_miss_req set
    963         // - r_dcache_unc_req set
    964         // - r_rsp_data_ok reset
    965         // - r_rsp_data_error reset
    966         // - r_dcache_cleanup_req set
     1022        // - r_dcache_miss_req (set)
     1023        // - r_dcache_unc_req (set)
     1024        // - r_rsp_data_ok (reset)
     1025        // - r_rsp_data_error (reset)
     1026        // - r_dcache_cleanup_req (set)
    9671027        // - r_dcache_cleanup_ine
    968         // - r_tgt_dcache_req reset
     1028        // - r_tgt_dcache_req (reset)
    9691029        // - r_tgt_dcache_rsp
    970         // - r_wbuf write()
    971         // - dreq & drsp structures for communication with the processor
     1030        // - r_wbuf (write)
     1031        // - dreq & drsp structures (communication with the processor)
    9721032        //
    9731033        // 1/ external request (invalidate or update)
     
    9821042        //   In order to support VCI write burst, the processor requests are taken into account
    9831043        //   in the WRITE_REQ state as well as in the IDLE state.
    984         //   - In the IDLE state, the processor request cannot be satisfied if
    985         //   there is a cached read miss, or an uncached read.
    986         //   - In the WRITE_REQ state, the request cannot be satisfied if
    987         //   there is a cached read miss, or an uncached read,
    988         //   or when the write buffer is full.
    989         //   - In all other states, the processor request is not satisfied.
     1044        // - In IDLE state, the request is satisfied if it is a cachable read hit,
     1045        //   an XTN request, or a cachable write.
     1046        // - In WRITE_REQ state, the request is satisfied if it is a cachable read hit,
     1047        //   an XTN request, or a write when the write buffer is not full.
     1048        // - Both the uncachable read and the uncachable write requests block the processor
     1049        //   until the corresponding VCI transaction is completed.
    9901050        //
    9911051        //   The cache access takes into account the cacheability_table.
    9921052        //   In case of processor request, there is six conditions to exit the IDLE state:
    993         //   - CACHED READ MISS => to the MISS_WAIT state, waiting the r_rsp_data_ok signal.
    994         //     It can be delayed in the MISS_DELAY state in case of matching pending
    995         //     cleanup request.  Then it goes to the MISS_UPDT state, then to the CLEANUP_REQ
    996         //     state (if necessary), and finally to the IDLE state.
    997         //   - UNCACHED READ  => to the UNC_WAIT state, waiting the r_rsp_data_ok signal,
    998         //     and back to the IDLE state. LL & SC are handled as uncached read.
    999         //   - WRITE MISS => directly to the WRITE_REQ state to post a request in the
    1000         //     write buffer.
     1053        //   - CACHED READ MISS => to the MISS_WAIT state (waiting r_rsp_data_ok),
     1054        //     then to the MISS_UPDT state, and finally to the IDLE state.
     1055        //   - UNCACHED READ or WRITE => to the UNC_WAIT state (waiting r_rsp_data_ok),
     1056        //     then to the UNC_GO state, and finally to the IDLE state.
     1057        //   - XTN_INVAL => to the INVAL state for one cycle, then to IDLE state.
     1058        //   - XTN_SYNC  => to the SYNC state until write buffer empty, then to IDLE state.
     1059        //   - WRITE MISS => directly to the WRITE_REQ state to access the write buffer.
    10011060        //   - WRITE HIT => to the WRITE_UPDT state, then to the WRITE_REQ state.
    1002         //   - LINE INVALIDATE => to the INVAL state for one cycle, then to IDLE state.
    1003         //   - SYNC REQUEST => to the SYNC state until the write buffer is empty.
     1061        //
     1062        //   All LL or SC requests are handled as uncachable.
    10041063        //
    10051064        // Error handling :  Read Bus Errors are synchronous events, but
     
    10221081                break;
    10231082            }
    1024             if( !r_wbuf.wok(r_dcache_addr_save) )
     1083            if( !r_wbuf.write(r_dcache_addr_save, r_dcache_be_save, r_dcache_wdata_save) )
    10251084            {
    10261085                // stay in DCACHE_WRITEREQ state if the write request is not accepted
    1027                 // by the write buffer
    10281086                m_cost_write_frz++;
    1029                 drsp.valid = false;
    1030                 drsp.rdata = 0;
    10311087                break;
    10321088            }
     
    10451101            if ( dreq.valid )
    10461102            {             
    1047                 bool        dcache_hit     = false;
    1048                 data_t      dcache_rdata   = 0;
    1049                 bool        dcache_cached;
     1103                bool        dcache_hit;
     1104                data_t      dcache_rdata;
     1105                bool        dcache_cachable;
     1106
     1107                // dcache_cachable, dcache_hit & dcache_rdata evaluation
    10501108                m_cpt_dcache_data_read += m_dcache_ways;
    10511109                m_cpt_dcache_dir_read += m_dcache_ways;
    1052 
    1053                 // dcache_cached evaluation
    1054                 switch (dreq.type) {
    1055                     case iss_t::DATA_LL:
    1056                     case iss_t::DATA_SC:
    1057                     case iss_t::XTN_READ:
    1058                     case iss_t::XTN_WRITE:
    1059                         dcache_cached = false;
    1060                         break;
    1061                     default:
    1062                         dcache_cached = m_cacheability_table[dreq.addr];
    1063                 }
    1064 
    1065                 // dcache_hit & dcache_rdata evaluation
    1066                 if ( dcache_cached )
    1067                 {
    1068                     dcache_hit = r_dcache.read((addr_t) dreq.addr, &dcache_rdata);
    1069                 }
    1070                 else
    1071                 {
    1072                     dcache_hit = ( r_rsp_data_ok && ( dreq.addr == r_dcache_addr_save) );
    1073                     dcache_rdata = r_dcache_miss_buf[0];
    1074                 }
    1075 
    1076                 // next state & response evaluation
    1077                 switch( dreq.type ) {
    1078                     case iss_t::DATA_READ:
    1079                     case iss_t::DATA_LL:
    1080                     case iss_t::DATA_SC:
    1081                         m_cpt_read++;
    1082                         if ( dcache_hit )
    1083                         {
    1084                             r_dcache_fsm = DCACHE_IDLE;
    1085                             drsp.valid = true;
    1086                             drsp.rdata = dcache_rdata;
    1087                             r_rsp_data_ok = false;
    1088                         }
    1089                         else           
    1090                         {
    1091                             if ( dcache_cached )   // miss
    1092                             {
    1093                                 m_cpt_data_miss++;
    1094                                 m_cost_data_miss_frz++;
    1095                                 // if the missing line corresponds to a pending cleanup
    1096                                 // the miss request to the CMD FSM must be delayed
    1097                                 if ( r_dcache_cleanup_req &&
    1098                                    ((addr_t)r_dcache_cleanup_line == (addr_t)(dreq.addr/(m_dcache_words*4))) )
    1099                                 {
    1100                                     break;
    1101                                 }
    1102                                 else
    1103                                 {
    1104                                     r_dcache_miss_req = true;
    1105                                     r_rsp_data_ok = false;
    1106                                     r_dcache_fsm = DCACHE_MISS_SELECT;
    1107                                 }
    1108                                 drsp.valid = false;
    1109                                 drsp.rdata = 0;
    1110                             }
    1111                             else                // uncached
    1112                             {
    1113                                 m_cpt_unc_read++;
    1114                                 m_cost_unc_read_frz++;
    1115                                 r_dcache_unc_req = true;
    1116                                 r_rsp_data_ok = false;
    1117                                 r_dcache_fsm = DCACHE_UNC_WAIT;
    1118                                 drsp.valid = false;
    1119                                 drsp.rdata = 0;
    1120                             }
    1121                         }
    1122                         break;
    1123                     case iss_t::XTN_READ:
    1124                     case iss_t::XTN_WRITE:
    1125                         // only DCACHE_INVAL & SYNC requests are supported
    1126                         if ( dreq.addr/4 == iss_t::XTN_DCACHE_INVAL )
    1127                         {
    1128                             r_dcache_fsm = DCACHE_INVAL;
    1129                         }
    1130                         else if ( dreq.addr/4 == iss_t::XTN_SYNC )
    1131                         {
    1132                             r_dcache_fsm = DCACHE_SYNC;
    1133                         }
    1134                         else
    1135                         {
    1136 //                          std::cout << "warning in VCI_CC_XCACHE_WRAPPER " << name() << std::endl;
    1137 //                          std::cout << "unsupported external access " << dreq.addr/4 << std::endl;
    1138 //                          std::cout << "only XTN_DCACHE_INVAL & XTN_SYNC are supported" << std::endl;
    1139                         }
    1140                         r_dcache_fsm = DCACHE_IDLE;
    1141                         drsp.valid = true;
    1142                         drsp.rdata = 0;
    1143                         break;
    1144                     case iss_t::DATA_WRITE:
    1145                         m_cpt_write++;
    1146                         if ( dcache_hit && dcache_cached )
    1147                         {
    1148                             m_cpt_write_cached++;
    1149                             r_dcache_fsm = DCACHE_WRITE_UPDT;
    1150                             drsp.valid = true;
    1151                             drsp.rdata = 0;
    1152                         }
    1153                         else
    1154                         {
    1155                             r_dcache_fsm = DCACHE_WRITE_REQ;
    1156                             drsp.valid = true;
    1157                             drsp.rdata = 0;
    1158                         }
    1159                         break;
    1160                 } // end switch dreq.type
    1161 
     1110                dcache_cachable     = m_cacheability_table[dreq.addr];
     1111                dcache_hit          = r_dcache.read(dreq.addr, &dcache_rdata);
     1112
     1113                // Save data request
    11621114                r_dcache_addr_save      = dreq.addr;
    11631115                r_dcache_type_save      = dreq.type;
     
    11651117                r_dcache_be_save        = dreq.be;
    11661118                r_dcache_rdata_save     = dcache_rdata;
    1167             }
    1168             else  // no dreq.valid
    1169             {
    1170                 drsp.valid      = false;
    1171                 drsp.rdata      = 0;
    1172                 r_dcache_fsm    = DCACHE_IDLE;
    1173             }
    1174             break;
    1175         }       
     1119
     1120                // reset r_rsp_data_ok
     1121                r_rsp_data_ok               = false;
     1122
     1123                // next FSM state, request to VCI, and processor response
     1124                if(dreq.type  == iss_t::DATA_READ)
     1125                {
     1126                    if(!dcache_cachable)                              // uncachable read
     1127                    {
     1128                        m_cpt_data_unc++;
     1129                        m_cost_unc_frz++;
     1130                        r_dcache_unc_req            = true;
     1131                        r_dcache_fsm                = DCACHE_UNC_WAIT;
     1132                    }
     1133                    else
     1134                    {
     1135                        m_cpt_read++;
     1136                        if(dcache_hit)                               // cachable read hit
     1137                        {
     1138                            drsp.valid          = true;
     1139                            drsp.rdata          = dcache_rdata;
     1140                            r_dcache_fsm        = DCACHE_IDLE;
     1141                        }
     1142                        else                                         // cachable read miss
     1143                        {
     1144                            m_cost_data_miss_frz++;
     1145                            // if the missing line corresponds to a pending cleanup
     1146                            // the miss request to the CMD FSM must be delayed
     1147                            if ( r_dcache_cleanup_req &&
     1148                               ((addr_t)r_dcache_cleanup_line == (addr_t)(dreq.addr/(m_dcache_words*4))) )
     1149                            {
     1150                                break;
     1151                            }
     1152                            else
     1153                            {
     1154                                m_cpt_data_miss++;
     1155                                r_dcache_miss_req       = true;
     1156                                r_dcache_fsm            = DCACHE_MISS_SELECT;
     1157                            }
     1158                        }
     1159                    }
     1160                }
     1161                else if(dreq.type == iss_t::DATA_WRITE)
     1162                {
     1163                    if(!dcache_cachable)                              // uncachable write
     1164                    {
     1165                        m_cpt_data_unc++;
     1166                        m_cost_unc_frz++;
     1167                        r_dcache_unc_req        = true;
     1168                        r_dcache_fsm            = DCACHE_UNC_WAIT;
     1169                    }
     1170                    else
     1171                    {
     1172                        m_cpt_write++;
     1173                        if(!dcache_hit)                              // cachable write miss
     1174                        {
     1175                            drsp.rdata          = 0;
     1176                            drsp.valid          = true;
     1177                            r_dcache_fsm        = DCACHE_WRITE_REQ;
     1178                        }
     1179                        else                                         // cachable write hit
     1180                        {
     1181                            m_cpt_write_cached++;
     1182                            drsp.rdata          = 0;
     1183                            drsp.valid          = true;
     1184                            r_dcache_fsm        = DCACHE_WRITE_UPDT;
     1185                        }
     1186                    }
     1187                }
     1188                else if(dreq.type == iss_t::DATA_LL)                        // linked read
     1189                //  all LL  requests are handled as uncachable 
     1190                {
     1191                    m_cpt_ll++;
     1192                    m_cost_unc_frz++;
     1193                    r_dcache_unc_req            = true;
     1194                    r_dcache_fsm                = DCACHE_UNC_WAIT;
     1195                }
     1196                else if(dreq.type == iss_t::DATA_SC)                        // conditional write
     1197                //  all SC requests are handled as uncachable   
     1198                {
     1199                    m_cpt_sc++;
     1200                    m_cost_unc_frz++;
     1201                    r_dcache_unc_req            = true;
     1202                    r_dcache_fsm                = DCACHE_UNC_WAIT;
     1203                }
     1204                else if((dreq.type == iss_t::XTN_WRITE) || (dreq.type == iss_t::XTN_READ))  // XTN access
     1205                // only INVAL & SYNC requests are supported
     1206                {
     1207                    drsp.valid = true;
     1208                    drsp.rdata = 0;
     1209                    if ( dreq.addr/4 == iss_t::XTN_DCACHE_INVAL )
     1210                    {
     1211                        r_dcache_fsm = DCACHE_INVAL;
     1212                    }
     1213                    else if ( dreq.addr/4 == iss_t::XTN_SYNC )
     1214                    {
     1215                        r_dcache_fsm = DCACHE_SYNC;
     1216                    }
     1217                    else if ( dreq.addr/4 == iss_t::XTN_TLB_MODE )
     1218                    {
     1219                        r_dcache_fsm = DCACHE_IDLE;
     1220                    }
     1221                    else
     1222                    {
     1223                        std::cout << "warning in VCI_CC_XCACHE_WRAPPER " << name() << std::endl;
     1224                        std::cout << "unsupported  external access : " << dreq.addr/4 << std::endl;
     1225                        std::cout << "only TLB_MODE, DCACHE_INVAL & SYNC are supported" << std::endl;
     1226                    }
     1227                }
     1228            }
     1229            else // no dreq.valid
     1230            {
     1231                r_dcache_fsm = DCACHE_IDLE;
     1232                drsp.valid = true;
     1233                drsp.rdata = 0;
     1234            }
     1235            break;
     1236        }
    11761237        case DCACHE_WRITE_UPDT:
    11771238        {
     
    11881249            size_t      way;
    11891250            addr_t      index;
    1190             addr_t  ad = r_dcache_addr_save;
    1191             if ( r_dcache.select_before_update( ad, &way, &index) )
     1251            addr_t      addr = r_dcache_addr_save;
     1252            if ( r_dcache.select_before_update( addr, &way, &index) )
    11921253            {
    11931254                r_dcache_fsm          = DCACHE_MISS_CLEANUP;
     
    12401301                    else
    12411302                    {
     1303                        // the cache is not updated in case of pending inval
    12421304                        r_dcache_cleanup_req = true;
    12431305                        r_dcache_cleanup_line = r_dcache_addr_save >> (uint32_log2(m_icache_words) + 2);
     
    12631325        case DCACHE_UNC_WAIT:
    12641326        {
    1265             if ( dreq.valid ) m_cost_unc_read_frz++;
     1327            if ( dreq.valid ) m_cost_unc_frz++;
    12661328            if ( r_tgt_dcache_req )    // external request
    12671329            {
     
    12721334            if ( r_rsp_data_ok )
    12731335            {
    1274                 if ( r_rsp_data_error ) r_dcache_fsm = DCACHE_ERROR;
    1275                 else
    1276                 {
    1277                     // If request is a DATA_SC we need to invalidate the corresponding cache line,
    1278                     // so that subsequent access to this line are read from RAM
    1279                     if (dreq.type == iss_t::DATA_SC)   
    1280                     {
    1281                         r_dcache_fsm = DCACHE_INVAL;
    1282                         r_dcache_wdata_save = r_dcache_addr_save;
    1283                     }
    1284                     else
    1285                     {
    1286                        r_dcache_fsm = DCACHE_IDLE;
    1287                     }
    1288                 }
    1289             }
     1336                if ( r_rsp_data_error )         r_dcache_fsm = DCACHE_ERROR;
     1337                else                            r_dcache_fsm = DCACHE_UNC_GO;
     1338            }
     1339            break;
     1340        }
     1341        case DCACHE_UNC_GO:
     1342        {
     1343            r_dcache_fsm = DCACHE_IDLE;
     1344            drsp.valid = true;
     1345            drsp.rdata = r_dcache_miss_buf[0];
    12901346            break;
    12911347        }
     
    12981354            break;
    12991355        }
    1300         case DCACHE_INVAL:
     1356        case DCACHE_INVAL:  // local inval requiring a cleanup in case of hit
    13011357        {
    13021358            if( !r_dcache_cleanup_req )
     
    13151371        }
    13161372        case DCACHE_CC_CHECK:   // read directory in case of external request
     1373        {
    13171374            m_cpt_dcache_dir_read += m_dcache_ways;
    13181375            m_cpt_dcache_data_read += m_dcache_ways;
    1319             if ( ( (r_dcache_fsm_save == DCACHE_MISS_WAIT) || (r_dcache_fsm_save == DCACHE_MISS_CLEANUP) ) && // external request matches a miss
     1376            if ( ( (r_dcache_fsm_save == DCACHE_MISS_WAIT) || (r_dcache_fsm_save == DCACHE_MISS_CLEANUP) ) &&
    13201377            ((r_dcache_addr_save & ~((m_dcache_words<<2)-1))==(r_tgt_addr & ~((m_dcache_words<<2)-1))))
    1321                 {
    1322                     r_dcache_inval_pending      = true;
    1323                     r_tgt_dcache_req            = false;
    1324                     r_tgt_dcache_rsp            = r_tgt_update; // always a response to an update
    1325                     r_dcache_fsm                = r_dcache_fsm_save;
     1378                    // external request matches a miss
     1379            {
     1380                r_dcache_inval_pending  = true;
     1381                r_tgt_dcache_req        = false;
     1382                r_tgt_dcache_rsp        = r_tgt_update; // always a response to an update
     1383                r_dcache_fsm            = r_dcache_fsm_save;
     1384            }
     1385            else  // the external request is not matching a pending miss
     1386            {
     1387                data_t  data;
     1388                bool    dcache_hit      = r_dcache.read(r_tgt_addr, &data);
     1389                if ( dcache_hit && r_tgt_update )  // hit update
     1390                {
     1391                    r_dcache_fsm = DCACHE_CC_UPDT;
    13261392                }
    1327                 else  // the external request is not matching a pending miss
    1328                 {
    1329                     data_t  data;
    1330                     bool    dcache_hit          = r_dcache.read(r_tgt_addr, &data);
    1331                     if ( dcache_hit && r_tgt_update )  // hit update
    1332                     {
    1333                         r_dcache_fsm = DCACHE_CC_UPDT;
    1334                     }
    1335                     else if ( dcache_hit && !r_tgt_update ) // hit inval
    1336                     {
    1337                         r_dcache_fsm = DCACHE_CC_INVAL;
    1338                     }
    1339                     else        // miss
    1340                     {
    1341                         r_tgt_dcache_req = false;
    1342                         r_tgt_dcache_rsp = r_tgt_update;  // always a respons in case of update
    1343                         r_dcache_fsm = r_dcache_fsm_save;
    1344                     }
    1345                 }
    1346                 break;
    1347            
    1348             case DCACHE_CC_UPDT:    // update the cache line       
    1349                 m_cpt_dcache_dir_write++;
    1350                 m_cpt_dcache_data_write++;
    1351                 for(size_t i=0; i<m_dcache_words; i++)
    1352                 {
    1353                     if(r_tgt_val[i]) r_dcache.write( (r_tgt_addr + i*4), r_tgt_buf[i] );
    1354                 }
    1355                 r_tgt_dcache_rsp = true;
    1356                 r_tgt_dcache_req = false;
    1357                 r_dcache_fsm = r_dcache_fsm_save;
    1358                 break;
    1359  
    1360             case DCACHE_CC_INVAL:   // invalidate a cache line
     1393                else if ( dcache_hit && !r_tgt_update ) // hit inval
     1394                {
     1395                    r_dcache_fsm = DCACHE_CC_INVAL;
     1396                }
     1397                else    // miss
     1398                {
     1399                    r_tgt_dcache_req = false;
     1400                    r_tgt_dcache_rsp = r_tgt_update;  // always a respons in case of update
     1401                    r_dcache_fsm = r_dcache_fsm_save;
     1402                }
     1403            }
     1404            break;
     1405        }   
     1406        case DCACHE_CC_UPDT:    // update the cache line       
     1407        {
     1408            m_cpt_dcache_dir_write++;
     1409            m_cpt_dcache_data_write++;
     1410            for(size_t i=0; i<m_dcache_words; i++)
     1411            {
     1412                if(r_tgt_val[i]) r_dcache.write( (r_tgt_addr + i*4), r_tgt_buf[i] );
     1413            }
     1414            r_tgt_dcache_rsp = true;
     1415            r_tgt_dcache_req = false;
     1416            r_dcache_fsm = r_dcache_fsm_save;
     1417            break;
     1418        }
     1419        case DCACHE_CC_INVAL:   // invalidate a cache line
     1420        {       
    13611421                r_dcache.inval(r_tgt_addr);
    13621422                r_tgt_dcache_rsp = true;
     
    13641424                r_dcache_fsm = r_dcache_fsm_save;
    13651425                break;
     1426        }
    13661427        } // end switch r_dcache_fsm
    13671428
    1368         ////////// write buffer handling //////////////////
    1369         if( r_dcache_fsm == DCACHE_WRITE_REQ )
    1370             r_wbuf.write(true, r_dcache_addr_save, r_dcache_be_save, r_dcache_wdata_save);
    1371         else
    1372             r_wbuf.write(false, 0, 0, 0);
     1429        ////////// write buffer state update  /////////////
     1430        // The update() method must be called at each cycle to update the internal state.
     1431        // All pending write requests must be locked in case of SYNC or in case of MISS.
     1432        if( (r_dcache_fsm == DCACHE_SYNC) || (r_dcache_fsm == DCACHE_MISS_WAIT) )
     1433        {
     1434            r_wbuf.update(true);
     1435        }
     1436        else
     1437        {
     1438            r_wbuf.update(false);
     1439        }
    13731440
    13741441#if SOCLIB_MODULE_DEBUG
    1375 if ( m_srcid_d == 0 )
    13761442std::cout << ireq << std::endl << irsp << std::endl << dreq << std::endl << drsp << std::endl;
    13771443#endif
     
    13911457        // on the coherence network. It controls the following ressources:
    13921458        // - r_cleanup_fsm
    1393         // - r_dcache_cleanup_req reset
    1394         // - r_icache_cleanup_req reset
     1459        // - r_dcache_cleanup_req (reset)
     1460        // - r_icache_cleanup_req (reset)
    13951461        //
    13961462        // This FSM handles cleanup requests from both the DCACHE FSM & ICACHE FSM
    1397         // 1 - Instruction Cleanup  : r_icache_cleanup_req
    1398         // 2 - Data Cleanup         : r_dcache_cleanup_req
     1463        // - Instruction Cleanup  : r_icache_cleanup_req
     1464        // - Data Cleanup         : r_dcache_cleanup_req
    13991465        // In case of simultaneous requests, the data request have highest priority.
    14001466        // There is only one cleanup transaction at a given time (sequencial behavior)
     
    14091475        switch (r_cleanup_fsm) {
    14101476
    1411             case CLEANUP_CMD:
     1477            case CLEANUP_IDLE:
    14121478            {   
    14131479                if ( p_vci_ini_c.cmdack )
    14141480                {
    1415                     if      (r_dcache_cleanup_req)      r_cleanup_fsm = CLEANUP_DCACHE_RSP;
    1416                     else if (r_icache_cleanup_req)      r_cleanup_fsm = CLEANUP_ICACHE_RSP;
    1417                 }
    1418                 break;
    1419             }
    1420             case CLEANUP_DCACHE_RSP:
     1481                    if      (r_dcache_cleanup_req)      r_cleanup_fsm = CLEANUP_DCACHE;
     1482                    else if (r_icache_cleanup_req)      r_cleanup_fsm = CLEANUP_ICACHE;
     1483                }
     1484                break;
     1485            }
     1486            case CLEANUP_DCACHE:
    14211487            {
    14221488                if ( p_vci_ini_c.rspval )
     
    14271493                      "error signaled in a cleanup response" );
    14281494                   
    1429                     r_cleanup_fsm = CLEANUP_CMD;
     1495                    r_cleanup_fsm = CLEANUP_IDLE;
    14301496                    r_dcache_cleanup_req = false;
    1431                 }
    1432                 break;
    1433             }
    1434             case CLEANUP_ICACHE_RSP:
     1497                    m_cpt_cc_cleanup_data++;
     1498                }
     1499                break;
     1500            }
     1501            case CLEANUP_ICACHE:
    14351502            {
    14361503                if ( p_vci_ini_c.rspval )
     
    14411508                      "error signaled in a cleanup response" );
    14421509                   
    1443                     r_cleanup_fsm = CLEANUP_CMD;
     1510                    r_cleanup_fsm = CLEANUP_IDLE;
    14441511                    r_icache_cleanup_req = false;
     1512                    m_cpt_cc_cleanup_ins++;
    14451513                }
    14461514                break;
     
    14641532        // There is 5 request types, with the following priorities :
    14651533        // 1 - Data Read Miss       : r_dcache_miss_req (if no hit in the write buffer)
    1466         // 2 - Data Read Uncached   : r_dcache_unc_req (if no hit in the write buffer)
     1534        // 2 - Data Read Uncachable   : r_dcache_unc_req (if no hit in the write buffer)
    14671535        // 3 - Instruction Miss     : r_icache_miss_req (if no hit in the write buffer)
    1468         // 4 - Instruction Uncached : r_icache_unc_req (if no hit in the write buffer)
     1536        // 4 - Instruction Uncachable : r_icache_unc_req (if no hit in the write buffer)
    14691537        // 5 - Data Write           : r_wbuf.rok()     
    14701538        // The read requests have highest priority, because the processor is blocked.
     
    14721540        // VCI formats:
    14731541        // According to the VCI advanced specification, all read requests packets
    1474         // (read Uncached, Miss data, Miss instruction) are one word packets.
     1542        // (read Uncachable, Miss data, Miss instruction) are one word packets.
    14751543        // For write burst packets, all words must be in the same cache line,
    14761544        // and addresses must be contiguous (the BE field is 0 in case of "holes").
    14771545        // The PLEN VCI field is always documented.
    1478         // - Read transactions  : index = 4*cached + 2*instruction  (even values)
    1479         //////////////////////////////////////////////////////////////////////////////
     1546        // As simultaneous VCI transactions are supported, the TRDID field is used:
     1547        // - Write transactions : TRDID = wbuf_index + (1<<(trdid_size-1))
     1548        // - Read transactions  : TRDID = 2*cachable + instruction 
     1549        ///////////////////////////////////////////////////////////////////////////////////
    14801550
    14811551        switch (r_cmd_fsm) {
    14821552
    14831553            case CMD_IDLE:
     1554            {
     1555                size_t  min;
     1556                size_t  max;
    14841557                if ( r_dcache_miss_req & r_wbuf.miss( r_dcache_addr_save ) )
    14851558                {
     
    14881561                    m_cpt_dmiss_transaction++;
    14891562                }
    1490                 else if ( r_dcache_unc_req & r_wbuf.miss( r_dcache_addr_save ) )
    1491                 {
    1492                     r_cmd_fsm = CMD_DATA_UNC;
    1493                     r_dcache_unc_req = false;
    1494                     m_cpt_unc_transaction++;
    1495                 }
    14961563                else if ( r_icache_miss_req & r_wbuf.miss( r_icache_addr_save ) )
    14971564                {
     
    15001567                    m_cpt_imiss_transaction++;
    15011568                }
    1502                 else if ( r_icache_unc_req & r_wbuf.miss( r_icache_addr_save ) )
     1569                else if ( r_wbuf.rok(&min, &max) )
     1570                {
     1571                    r_cmd_fsm = CMD_DATA_WRITE;
     1572                    r_cmd_cpt = min;
     1573                    r_cmd_min = min;
     1574                    r_cmd_max = max;
     1575                    m_cpt_write_transaction++;
     1576                    m_length_write_transaction += (max-min+1);
     1577                }
     1578                else if ( r_dcache_unc_req )
     1579                {
     1580                    r_cmd_fsm = CMD_DATA_UNC;
     1581                    r_dcache_unc_req = false;
     1582                    m_cpt_data_unc_transaction++;
     1583                }
     1584                else if ( r_icache_unc_req )
    15031585                {
    15041586                    r_cmd_fsm = CMD_INS_UNC;
    15051587                    r_icache_unc_req = false;
    1506                     m_cpt_imiss_transaction++;
    1507                 }
    1508                 else if ( r_wbuf.rok() )
    1509                 {
    1510                     r_cmd_fsm = CMD_DATA_WRITE;
    1511                     r_cmd_cpt = r_wbuf.getMin();
    1512                     r_cmd_min = r_wbuf.getMin();
    1513                     r_cmd_max = r_wbuf.getMax();
    1514                     m_cpt_write_transaction++;
    1515                     m_length_write_transaction += (r_wbuf.getMax() - r_wbuf.getMin() + 1);
    1516                 }
    1517                 break;
    1518 
     1588                    m_cpt_ins_unc_transaction++;
     1589                }
     1590                break;
     1591            }
    15191592            case CMD_DATA_WRITE:
     1593            {
    15201594                if ( p_vci_ini_d.cmdack.read() )
    15211595                {
     
    15281602                }
    15291603                break;
    1530 
     1604            }
    15311605            case CMD_INS_MISS:
    15321606            case CMD_INS_UNC:
    15331607            case CMD_DATA_MISS:
    15341608            case CMD_DATA_UNC:
     1609            {
    15351610                if ( p_vci_ini_d.cmdack.read() )  r_cmd_fsm = CMD_IDLE;
    15361611                break;
     1612            }
    15371613        } // end  switch r_cmd_fsm
    15381614
     
    15571633        // VCI formats:
    15581634        // This component accepts only single word write response packets.
     1635        // As simultaneous VCI transactions are supported, the TRDID field is used:
     1636        // - Write transactions : TRDID = wbuf_index + (1<<(trdid_size-1))
     1637        // - Read transactions  : TRDID = 2*cachable + instruction 
    15591638        //
    15601639        // Error handling:
    1561         // This FSM analyzes the VCI error code and signals the  Write Bus Error.
    1562         // In case of Read Data Error, the VCI_RSP FSM sets the r_rsp_data_error
    1563         // flip_flop and the error is signaled by the DCACHE FSM. 
    1564         // In case of Instruction Error, the VCI_RSP FSM sets the r_rsp_ins_error
    1565         // flip_flop and the error is signaled by the DCACHE FSM. 
     1640        // - In case of Write error, the error is directly signaled by the RSP FSM.
     1641        // - In case of Read Data Error, the VCI_RSP FSM sets the r_rsp_data_error
     1642        //   flip_flop and the error is signaled by the DCACHE FSM. 
     1643        // - In case of Instruction Error, the VCI_RSP FSM sets the r_rsp_ins_error
     1644        //   flip_flop and the error is signaled by the ICACHE FSM. 
    15661645        //////////////////////////////////////////////////////////////////////////
     1646        // Implementation note
     1647        // It should be possible to save one cycle on the MISS cost by a simple
     1648        // modification of this RSP FSM : The first flit of a valid response
     1649        // could be decoded and handled directly in the IDLE state.
     1650        // The computation of the RSPACK condition become more complex...
     1651        //////////////////////////////////////////////////////////////////////////:
    15671652
    15681653        switch (r_rsp_fsm) {
    15691654
    15701655        case RSP_IDLE:
     1656        {
    15711657            if( p_vci_ini_d.rspval.read() )
    15721658            {
    15731659                r_rsp_cpt = 0;
    1574                 if ( p_vci_ini_d.rtrdid.read()/m_wbuf_nlines != 0 )             r_rsp_fsm = RSP_DATA_WRITE;
    1575                 else if ( p_vci_ini_d.rtrdid.read() == TYPE_DATA_MISS ) r_rsp_fsm = RSP_DATA_MISS;
    1576                 else if ( p_vci_ini_d.rtrdid.read() == TYPE_DATA_UNC )  r_rsp_fsm = RSP_DATA_UNC;
    1577                 else if ( p_vci_ini_d.rtrdid.read() == TYPE_INS_MISS )  r_rsp_fsm = RSP_INS_MISS;
    1578                 else if ( p_vci_ini_d.rtrdid.read() == TYPE_INS_UNC )   r_rsp_fsm = RSP_INS_UNC;
    1579             }
    1580             break;
    1581 
     1660                if ( (p_vci_ini_d.rtrdid.read()>>(vci_param::T-1)) != 0 )       r_rsp_fsm = RSP_DATA_WRITE;
     1661                else if ( p_vci_ini_d.rtrdid.read() == TYPE_DATA_MISS )         r_rsp_fsm = RSP_DATA_MISS;
     1662                else if ( p_vci_ini_d.rtrdid.read() == TYPE_DATA_UNC )          r_rsp_fsm = RSP_DATA_UNC;
     1663                else if ( p_vci_ini_d.rtrdid.read() == TYPE_INS_MISS )          r_rsp_fsm = RSP_INS_MISS;
     1664                else if ( p_vci_ini_d.rtrdid.read() == TYPE_INS_UNC )           r_rsp_fsm = RSP_INS_UNC;
     1665            }
     1666            break;
     1667        }
    15821668        case RSP_DATA_WRITE:
     1669        {
    15831670            if ( p_vci_ini_d.rspval.read() )
    15841671            {
    15851672                assert(p_vci_ini_d.reop.read() &&
    1586                    "illegal VCI response packet for a write transaction");
     1673                   "A VCI response packet must contain one flit for a write transaction");
    15871674                r_rsp_fsm = RSP_IDLE;
    1588                 r_wbuf.completed( p_vci_ini_d.rtrdid.read() - m_wbuf_nlines );
     1675                r_wbuf.completed( p_vci_ini_d.rtrdid.read() - (1<<(vci_param::T-1)) );
    15891676                if ( p_vci_ini_d.rerror.read() != vci_param::ERR_NORMAL ) m_iss.setWriteBerr();
    15901677            }
    15911678            break;
    1592 
     1679        }
    15931680        case RSP_INS_MISS:
     1681        {
    15941682            if ( p_vci_ini_d.rspval.read() )
    15951683            { 
     
    16071695            }
    16081696            break;
    1609 
     1697        }
    16101698        case RSP_INS_UNC:
     1699        {
    16111700            if ( p_vci_ini_d.rspval.read() )
    16121701            {
    16131702                assert(p_vci_ini_d.reop.read() &&
    1614                    "illegal VCI response packet for uncached instruction");
     1703                   "illegal VCI response packet for uncachable instruction");
    16151704                r_icache_miss_buf[0] = (data_t)p_vci_ini_d.rdata.read();
    16161705                r_rsp_ins_ok = true;
     
    16191708            }
    16201709            break;
    1621 
     1710        }
    16221711        case RSP_DATA_MISS:
     1712        {
    16231713            if ( p_vci_ini_d.rspval.read() )
    16241714            {
    1625                 assert(r_rsp_cpt != m_dcache_words &&
    1626                    "illegal VCI response packet for data read miss");
     1715                assert( (r_rsp_cpt < m_dcache_words) &&
     1716                        "The VCI response packet for data miss is too long" );
    16271717                r_rsp_cpt = r_rsp_cpt + 1;
    16281718                r_dcache_miss_buf[r_rsp_cpt] = (data_t)p_vci_ini_d.rdata.read();
     
    16301720                {
    16311721                    assert(r_rsp_cpt == m_dcache_words - 1 &&
    1632                        "illegal VCI response packet for instruction miss");
     1722                        "The VCI response packet for data miss is too short" );
    16331723                    r_rsp_data_ok = true;
    16341724                    r_rsp_fsm = RSP_IDLE;
     
    16371727            }
    16381728            break;
    1639 
     1729        }
    16401730        case RSP_DATA_UNC:
     1731        {
    16411732            if ( p_vci_ini_d.rspval.read() )
    16421733            {
    16431734                assert(p_vci_ini_d.reop.read() &&
    1644                    "illegal VCI response packet for uncached read data");
     1735                   "illegal VCI response packet for uncachable data");
    16451736                r_dcache_miss_buf[0] = (data_t)p_vci_ini_d.rdata.read();
    16461737                r_rsp_data_ok = true;
     
    16491740            }
    16501741            break;
     1742        }
    16511743        } // end switch r_rsp_fsm
    16521744
    16531745    } // end transition()
    16541746
    1655     //////////////////////////////////////////////////////////////////////////////////
     1747    //////////////////////
    16561748    tmpl(void)::genMoore()
    1657     //////////////////////////////////////////////////////////////////////////////////
    16581749    {
    16591750        // Coherence network (initiator port)
     
    16611752        switch ( r_cleanup_fsm.read() ) {
    16621753
    1663             case CLEANUP_CMD:
     1754            case CLEANUP_IDLE:
    16641755                p_vci_ini_c.rspack  = false;
    16651756                p_vci_ini_c.cmdval  = r_icache_cleanup_req || r_dcache_cleanup_req;
    16661757                if ( r_dcache_cleanup_req )
    16671758                {
    1668                     p_vci_ini_c.address =  r_dcache_cleanup_line.read() * m_dcache_words * 4;
     1759                    p_vci_ini_c.address =  r_dcache_cleanup_line.read() * (m_dcache_words << 2);
    16691760                    p_vci_ini_c.trdid   = 0;
    16701761                }
    16711762                else
    16721763                {
    1673                     p_vci_ini_c.address =  r_icache_cleanup_line.read() * (m_icache_words << 2); //* 4;
     1764                    p_vci_ini_c.address =  r_icache_cleanup_line.read() * (m_icache_words << 2);
    16741765                    p_vci_ini_c.trdid   = 1;
    16751766                }
     
    16881779                break;
    16891780
    1690            case CLEANUP_DCACHE_RSP:
     1781           case CLEANUP_DCACHE:
    16911782                p_vci_ini_c.rspack  = true;
    16921783                p_vci_ini_c.cmdval  = false;
     
    17071798                break;
    17081799
    1709            case CLEANUP_ICACHE_RSP:
     1800           case CLEANUP_ICACHE:
    17101801                p_vci_ini_c.rspack  = true;
    17111802                p_vci_ini_c.cmdval  = false;
     
    17551846            case CMD_DATA_WRITE:
    17561847                p_vci_ini_d.cmdval  = true;
    1757                 p_vci_ini_d.address = r_wbuf.getAddress(r_cmd_cpt)&~0x3;
     1848                p_vci_ini_d.address = r_wbuf.getAddress(r_cmd_cpt);
    17581849                p_vci_ini_d.wdata   = r_wbuf.getData(r_cmd_cpt);
    17591850                p_vci_ini_d.be      = r_wbuf.getBe(r_cmd_cpt);
    17601851                p_vci_ini_d.plen    = (r_cmd_max - r_cmd_min + 1)<<2;
    17611852                p_vci_ini_d.cmd     = vci_param::CMD_WRITE;
     1853                p_vci_ini_d.trdid   = r_wbuf.getIndex() + (1<<(vci_param::T-1));
    17621854                p_vci_ini_d.pktid   = 0;
    1763                 p_vci_ini_d.trdid   = r_wbuf.getIndex() + m_wbuf_nlines;
    17641855                p_vci_ini_d.srcid   = m_srcid_d;
    17651856                p_vci_ini_d.cons    = false;
     
    17711862                break;
    17721863
     1864            case CMD_DATA_MISS:
     1865                p_vci_ini_d.cmdval = true;
     1866                p_vci_ini_d.address = r_dcache_addr_save & (addr_t)m_dcache_yzmask;
     1867                p_vci_ini_d.be     = 0xF;
     1868                p_vci_ini_d.plen   = m_dcache_words << 2;
     1869                p_vci_ini_d.cmd    = vci_param::CMD_READ;
     1870                p_vci_ini_d.trdid  = TYPE_DATA_MISS;
     1871                p_vci_ini_d.pktid  = 0;
     1872                p_vci_ini_d.srcid  = m_srcid_d;
     1873                p_vci_ini_d.cons   = false;
     1874                p_vci_ini_d.wrap   = false;
     1875                p_vci_ini_d.contig = true;
     1876                p_vci_ini_d.clen   = 0;
     1877                p_vci_ini_d.cfixed = false;
     1878                p_vci_ini_d.eop    = true;
     1879                break;
     1880
    17731881            case CMD_DATA_UNC:
    17741882                p_vci_ini_d.cmdval = true;
    17751883                p_vci_ini_d.address = r_dcache_addr_save & ~0x3;
    17761884                switch( r_dcache_type_save ) {
     1885                    case iss_t::DATA_WRITE:
     1886                        p_vci_ini_d.wdata = r_dcache_wdata_save.read();
     1887                        p_vci_ini_d.be  = r_dcache_be_save.read();
     1888                        p_vci_ini_d.cmd = vci_param::CMD_WRITE;
     1889                        break;
    17771890                    case iss_t::DATA_READ:
    17781891                        p_vci_ini_d.wdata = 0;
     
    17931906                        assert("this should not happen");
    17941907                }
    1795                 p_vci_ini_d.plen = 4;
     1908                p_vci_ini_d.plen   = 4;
    17961909                p_vci_ini_d.trdid  = TYPE_DATA_UNC;
    17971910                p_vci_ini_d.pktid  = 0;
     
    18051918                break;
    18061919
    1807             case CMD_DATA_MISS:
    1808                 p_vci_ini_d.cmdval = true;
    1809                 p_vci_ini_d.address = r_dcache_addr_save.read() & (addr_t) m_dcache_yzmask;
    1810                 p_vci_ini_d.be     = 0xF;
    1811                 p_vci_ini_d.plen   = m_dcache_words << 2;
    1812                 p_vci_ini_d.cmd    = vci_param::CMD_READ;
    1813                 p_vci_ini_d.trdid  = TYPE_DATA_MISS;
    1814                 p_vci_ini_d.pktid  = 0;
    1815                 p_vci_ini_d.srcid  = m_srcid_d;
    1816                 p_vci_ini_d.cons   = false;
    1817                 p_vci_ini_d.wrap   = false;
    1818                 p_vci_ini_d.contig = true;
    1819                 p_vci_ini_d.clen   = 0;
    1820                 p_vci_ini_d.cfixed = false;
    1821                 p_vci_ini_d.eop    = true;
    1822                 break;
    1823 
    18241920            case CMD_INS_MISS:
    18251921                p_vci_ini_d.cmdval = true;
    1826                 p_vci_ini_d.address = r_icache_addr_save & (addr_t) m_icache_yzmask;
     1922                p_vci_ini_d.address = r_icache_addr_save & (addr_t)m_icache_yzmask;
    18271923                p_vci_ini_d.be     = 0xF;
    18281924                p_vci_ini_d.plen   = m_icache_words << 2;
Note: See TracChangeset for help on using the changeset viewer.