Changeset 291


Ignore:
Timestamp:
Jan 28, 2013, 1:59:32 PM (11 years ago)
Author:
joannou
Message:

Introducing new generic_llsc_local_table and generic_llsc_global_table components :
These two tables implement the new scalable LL/SC mechanism for TSAR.

  • generic_llsc_local_table, integrated in the vci_cc_vache_wrapper_v4 component. The table is accessed by the DCACHE_FSM. A two step registration (LL cmd/ LL rsp) sets a signature allocated by the global table for the pending LL/SC operation. An SC operation consumes the registration.
  • generic_llsc_global_table, integrated in the vci_mem_cache_v4 component. The table is accessed by the READ_FSM, WRITE_FSM, CAS_FSM, when accessing the directory. It generates a signature for LL registrations and performs SC operation by checking registration's valididty with that signature. SW operations simply invalidate a registrations.

N.B. :

  • The sizes of the tables are parameters, and are NOT a function of the architecture's size (scalable mechanism).
  • The LL are handled by the MEMCACHE in the READ_FSM.
  • The SC are handled by the MEMCACHE in the WRITE_FSM, and are no longer CAS emulated. CAS operation is now only performed by hardware mechanisms.
  • An extra field is added to the xram transaction table to save a pending LL's signature.
Location:
trunk
Files:
10 added
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/modules/vci_cc_vcache_wrapper_v4/caba/metadata/vci_cc_vcache_wrapper_v4.sd

    r183 r291  
    1616                 Uses('caba:generic_fifo'),
    1717                 Uses('caba:generic_cam'),
     18                 Uses('caba:generic_llsc_local_table'),
    1819                 Uses('caba:generic_cache',
    1920                       addr_t = parameter.StringExt('sc_dt::sc_uint<%d> ',
  • trunk/modules/vci_cc_vcache_wrapper_v4/caba/source/include/vci_cc_vcache_wrapper_v4.h

    r284 r291  
    3737#include "generic_cache.h"
    3838#include "generic_cam.h"
     39#include "generic_llsc_local_table.h"
    3940#include "vci_initiator.h"
    4041#include "vci_target.h"
     
    6061
    6162    typedef typename vci_param::addr_t  paddr_t;
     63    typedef typename vci_param::data_t  vci_data_t;
    6264    typedef typename vci_param::be_t    vci_be_t;
    6365    typedef typename vci_param::srcid_t vci_srcid_t;
     
    124126        DCACHE_MISS_WAIT,           
    125127        DCACHE_MISS_UPDT,           
    126         // handling processor unc and sc requests
     128        // handling processor unc, ll and sc requests
    127129        DCACHE_UNC_WAIT,           
     130        DCACHE_LL_WAIT,           
    128131        DCACHE_SC_WAIT,           
    129132        // handling coherence requests
     
    142145        CMD_DATA_UNC,
    143146        CMD_DATA_WRITE,
     147        CMD_DATA_LL,
     148        CMD_DATA_SC,
    144149        CMD_DATA_CAS,
    145150    };
     
    151156        RSP_DATA_MISS,
    152157        RSP_DATA_UNC,
     158        RSP_DATA_LL,
    153159        RSP_DATA_WRITE,
    154160    };
     
    400406    sc_signal<bool>         r_dcache_vci_unc_req;       // uncacheable read request
    401407    sc_signal<bool>         r_dcache_vci_unc_be;        // uncacheable read byte enable
    402     sc_signal<bool>         r_dcache_vci_sc_req;        // atomic write request (Compare & swap)
    403     sc_signal<uint32_t>     r_dcache_vci_sc_old;        // previous data value for an atomic write
    404     sc_signal<uint32_t>     r_dcache_vci_sc_new;        // new data value for an atomic write
     408    sc_signal<bool>         r_dcache_vci_cas_req;       // atomic write request CAS
     409    sc_signal<uint32_t>     r_dcache_vci_cas_old;       // previous data value for an atomic write CAS
     410    sc_signal<uint32_t>     r_dcache_vci_cas_new;       // new data value for an atomic write CAS
     411    sc_signal<bool>         r_dcache_vci_ll_req;        // atomic read request LL
     412    sc_signal<bool>         r_dcache_vci_sc_req;        // atomic write request SC
     413    sc_signal<vci_data_t>   r_dcache_vci_sc_data;       // SC data (command)
    405414
    406415    // register used for XTN inval
     
    425434    // dcache flush handling
    426435    sc_signal<size_t>       r_dcache_flush_count;           // slot counter used for cache flush
     436
     437    // ll rsp handling
     438    sc_signal<size_t>       r_dcache_ll_rsp_count;          // flit counter used for ll rsp
     439
     440    // sc cmd handling
     441    sc_signal<vci_data_t>   r_sc_key;                   // SC key returned by local table
    427442
    428443    // used by the TLB miss sub-fsm
     
    438453    sc_signal<size_t>       r_dcache_tlb_set;               // selected set in tlb   
    439454
    440     // LL reservation handling
    441     sc_signal<bool>         r_dcache_ll_valid;              // valid LL reservation
    442     sc_signal<uint32_t>     r_dcache_ll_data;               // LL reserved data
    443     sc_signal<paddr_t>      r_dcache_ll_vaddr;              // LL reserved address
    444                            
    445455    // ITLB and DTLB invalidation
    446456    sc_signal<paddr_t>      r_dcache_tlb_inval_line;    // line index
     
    517527    GenericTlb<paddr_t>         r_itlb;
    518528    GenericTlb<paddr_t>         r_dtlb;
     529
     530    //////////////////////////////////////////////////////////////////
     531    // llsc local registration table
     532    //////////////////////////////////////////////////////////////////
     533
     534    #define LLSCLocalTable GenericLLSCLocalTable<8000, 1, paddr_t, vci_trdid_t, vci_data_t>
     535    LLSCLocalTable r_llsc_table;                    // The llsc local registration table
     536
     537    typename LLSCLocalTable::in_t   table_in    ;   // llsc local table input signals
     538    typename LLSCLocalTable::out_t  table_out   ;   // llsc local table output signals
     539
     540    #undef LLSCLocalTable
    519541
    520542    ////////////////////////////////
  • trunk/modules/vci_cc_vcache_wrapper_v4/caba/source/src/vci_cc_vcache_wrapper_v4.cpp

    r288 r291  
    9797
    9898        "DCACHE_UNC_WAIT",   
     99        "DCACHE_LL_WAIT",   
    99100        "DCACHE_SC_WAIT",   
    100101
     
    112113        "CMD_DATA_UNC",     
    113114        "CMD_DATA_WRITE",
     115        "CMD_DATA_LL",
     116        "CMD_DATA_SC",
    114117        "CMD_DATA_CAS",
    115118    };
     
    120123        "RSP_DATA_MISS",             
    121124        "RSP_DATA_UNC",             
     125        "RSP_DATA_LL",
    122126        "RSP_DATA_WRITE",     
    123127    };
     
    277281      r_dcache_vci_unc_req("r_dcache_vci_unc_req"),
    278282      r_dcache_vci_unc_be("r_dcache_vci_unc_be"),
     283      r_dcache_vci_cas_req("r_dcache_vci_cas_req"),
     284      r_dcache_vci_cas_old("r_dcache_vci_cas_old"),
     285      r_dcache_vci_cas_new("r_dcache_vci_cas_new"),
     286      r_dcache_vci_ll_req("r_dcache_vci_ll_req"),
    279287      r_dcache_vci_sc_req("r_dcache_vci_sc_req"),
    280       r_dcache_vci_sc_old("r_dcache_vci_sc_old"),
    281       r_dcache_vci_sc_new("r_dcache_vci_sc_new"),
     288      r_dcache_vci_sc_data("r_dcache_vci_sc_data"),
    282289
    283290      r_dcache_xtn_way("r_dcache_xtn_way"),
     
    307314      r_dcache_tlb_way("r_dcache_tlb_way"),
    308315      r_dcache_tlb_set("r_dcache_tlb_set"),
    309 
    310       r_dcache_ll_valid("r_dcache_ll_valid"),
    311       r_dcache_ll_data("r_dcache_ll_data"),
    312       r_dcache_ll_vaddr("r_dcache_ll_vaddr"),
    313316
    314317      r_dcache_tlb_inval_line("r_dcache_tlb_inval_line"),
     
    666669/////////////////////////
    667670{
     671    #define LLSCLocalTable GenericLLSCLocalTable<8000, 1, paddr_t, vci_trdid_t, vci_data_t>
    668672    if ( not p_resetn.read() )
    669673    {
     
    714718        r_dcache_vci_miss_req      = false;
    715719        r_dcache_vci_unc_req       = false;
     720        r_dcache_vci_cas_req       = false;
     721        r_dcache_vci_ll_req        = false;
    716722        r_dcache_vci_sc_req        = false;
    717723
    718724        // No uncacheable write pending
    719725        r_dcache_pending_unc_write = false;
    720 
    721         // No LL reservation
    722             r_dcache_ll_valid          = false;
    723726
    724727        // No processor XTN request pending
     
    854857        for (uint32_t i=0; i<32 ; ++i) m_cpt_fsm_cmd_cleanup [i]   = 0;
    855858        for (uint32_t i=0; i<32 ; ++i) m_cpt_fsm_rsp_cleanup [i]   = 0;
     859
     860        // init the llsc local registration table
     861        r_llsc_table.init();
    856862
    857863        return;
     
    19361942    // 4/ Atomic instructions LL/SC
    19371943    //    The LL/SC address can be cacheable or non cacheable.
    1938     //    The reservation registers (r_dcache_ll_valid, r_dcache_ll_vaddr and
    1939     //    r_dcache_ll_data are stored in the L1 cache controller, and not in the
    1940     //    memory controller.
    1941     //    - LL requests from the processor are transmitted as standard VCI
    1942     //      READ transactions (one word / one line, depending on the cacheability).
     1944    //    The llsc_local_table holds a registration for an active LL/SC
     1945    //    operation (with an address, a registration key, an aging counter and a
     1946    //    valid bit).
     1947    //    - LL requests from the processor are transmitted as a one flit VCI
     1948    //      CMD_LOCKED_READ transaction with TYPE_LL as PKTID value. PLEN must
     1949    //      be 8 as the response is 2 flits long (data and registration key)
    19431950    //    - SC requests from the processor are systematically transmitted to the
    1944     //      memory cache as Compare&swap requests (both the data value stored in the
    1945     //      r_dcache_ll_data register and the new value).
     1951    //      memory cache as 2 flits VCI CMD_NOP (or CMD_STORE_COND)
     1952    //      transactions, with TYPE_SC as PKTID value (the first flit contains
     1953    //      the registration key, the second flit contains the data to write in
     1954    //      case of success).
    19461955    //      The cache is not updated, as this is done in case of success by the
    19471956    //      coherence transaction.
     
    19741983    m_drsp.error = false;
    19751984    m_drsp.rdata = 0;
     1985   
     1986    // keep track of the local llsc table access and perform a NOP access if
     1987    // necessary at the end of the DCACHE transition function
     1988    bool llsc_local_table_access_done = false;
    19761989
    19771990    switch ( r_dcache_fsm.read() )
    19781991    {
    1979     case DCACHE_IDLE:   // There is 8 conditions to exit the IDLE state :
     1992    case DCACHE_IDLE:   // There are 9 conditions to exit the IDLE state :
    19801993                                                // 1) Dirty bit update (processor)    => DCACHE_DIRTY_GET_PTE
    19811994                                                // 2) Coherence request (TGT FSM)     => DCACHE_CC_CHECK
     
    19851998                                                // 6) Cacheable read miss (processor) => DCACHE_MISS_VICTIM
    19861999                                                // 7) Uncacheable read (processor)    => DCACHE_UNC_WAIT
    1987                                                 // 8) SC access (processor)           => DCACHE_SC_WAIT
     2000                                                // 8) LL access (processor)           => DCACHE_LL_WAIT
     2001                                                // 9) SC access (processor)           => DCACHE_SC_WAIT
    19882002                        //
    19892003                        // The dtlb is unconditionally accessed to translate the
     
    21502164        //    dtlb miss. If dtlb is OK, It enters the three stage pipe-line (fully
    21512165        //    handled by the IDLE state), and the processor request is acknowledged.
    2152         // 2) A processor READ or LL request generate a simultaneouss access to
     2166        // 2) A processor READ request generate a simultaneouss access to
    21532167        //    both dcache data and dcache directoty, using speculative PPN, but
    21542168        //    is delayed if the write pipe-line is not empty.
    21552169        //    In case of miss, we wait the VCI response in DCACHE_UNC_WAIT or
    21562170        //    DCACHE_MISS_WAIT states.
    2157         // 3) A processor SC request is delayed until the write pipe-line is empty.
     2171        // 3) A processor LL request generate a VCI LL transaction. We wait for
     2172        //    the response in DCACHE_LL_WAIT state.
     2173        // 4) A processor SC request is delayed until the write pipe-line is empty.
    21582174        //    A VCI SC transaction is launched, and we wait the VCI response in
    21592175        //    DCACHE_SC_WAIT state. It can be completed by a "long write" if the
     
    25352551                    r_dcache_p0_cacheable      = cacheable;
    25362552
    2537                     // READ or LL request
     2553                    // READ request
    25382554                    // The read requests are taken only if the write pipe-line is empty.
    25392555                    // If dcache hit, dtlb hit, and speculative PPN OK, data in one cycle.
     
    25412557                    // If dcache miss, we go to DCACHE_MISS_VICTIM state.
    25422558                    // If uncacheable, we go to DCACHE_UNC_WAIT state.
    2543                     // In case of LL, the LL registration is done when the data is returned:
    2544                     // in DCACHE_IDLE if cacheable / in DCACHE_UNC_WAIT if uncacheable
    2545                     if ( ((m_dreq.type == iss_t::DATA_READ) or (m_dreq.type == iss_t::DATA_LL))
     2559                    if ( ((m_dreq.type == iss_t::DATA_READ))
    25462560                        and not r_dcache_p0_valid.read() and not r_dcache_p1_valid.read() )
    25472561                    {
     
    25812595                                m_drsp.valid   = true;
    25822596                                m_drsp.rdata   = cache_rdata;
    2583 
    2584                                 // makes reservation in case of LL
    2585                                 if ( m_dreq.type == iss_t::DATA_LL )
    2586                                 {
    2587                                     r_dcache_ll_valid = true;
    2588                                     r_dcache_ll_vaddr = m_dreq.addr;
    2589                                     r_dcache_ll_data  = cache_rdata;
    2590                                 }
    25912597#if DEBUG_DCACHE
    25922598if ( m_debug_dcache_fsm )
     
    26062612
    26072613                        r_dcache_p0_valid = false;
    2608                     } // end READ or LL
     2614                    } // end READ
     2615
     2616                    // LL request
     2617                    // The LL requests are taken only if the write pipe-line is empty.
     2618                    // We request an LL transaction to CMD FSM and go to
     2619                    // DCACHE_LL_WAIT state, that will return the response to
     2620                    // the processor.
     2621                    else if ( ((m_dreq.type == iss_t::DATA_LL))
     2622                        and not r_dcache_p0_valid.read() and not r_dcache_p1_valid.read() )
     2623                    {
     2624                        // prepare llsc local table access
     2625                        table_in.cmd       = LLSCLocalTable::LL_CMD ;
     2626                        table_in.address   = paddr;
     2627                        // access the table
     2628                        r_llsc_table.exec(table_in, table_out);
     2629                        llsc_local_table_access_done = true;
     2630                        // test if the table is done
     2631                        if(!table_out.done)
     2632                        {
     2633                            r_dcache_p0_valid     = false;
     2634                            break;
     2635                        }
     2636                        // request an LL CMD and go to DCACHE_LL_WAIT state
     2637                        r_dcache_vci_ll_req   = true;
     2638                        r_dcache_ll_rsp_count = 0;
     2639                        r_dcache_p0_valid     = false;
     2640                        r_dcache_vci_paddr    = paddr;
     2641                        r_dcache_fsm          = DCACHE_LL_WAIT;
     2642                    }// end LL
    26092643
    26102644                    // WRITE request:
     
    26402674m_cpt_data_write++;
    26412675#endif
     2676                            table_in.cmd       = LLSCLocalTable::SW_CMD ;
     2677                            table_in.address   = paddr;
     2678                            r_llsc_table.exec(table_in, table_out)  ;
     2679                            llsc_local_table_access_done = true;
     2680                            if(!table_out.done)
     2681                            {
     2682                                r_dcache_p0_valid     = false;
     2683                                break;
     2684                            }
    26422685                            m_drsp.valid      = true;
    26432686                            m_drsp.rdata      = 0;
     
    26482691                    // SC request:
    26492692                    // The SC requests are taken only if the write pipe-line is empty.
    2650                     // - if there is no valid registered LL, we just return rdata = 1
    2651                     //   (atomic access failed) and the SC transaction is completed.
    2652                     // - if a valid LL reservation (with the same address) is registered,
    2653                     //   we test if a DIRTY bit update is required.
    2654                     //   If the TLB is activated and the PTE Dirty bit is not set, we stall
    2655                     //   the processor and set the Dirty bit before handling the write request.
    2656                     //   If we don't need to set the Dirty bit, we request a SC transaction
    2657                     //   to CMD FSM and go to DCACHE_SC_WAIT state, that will return
    2658                     //   the response to the processor.
    2659                     //   We don't check a possible write hit in dcache, as the cache update
    2660                     //   is done by the coherence transaction induced by the SC...
     2693                    //  We test if a DIRTY bit update is required.
     2694                    //  If the TLB is activated and the PTE Dirty bit is not set, we stall
     2695                    //  the processor and set the Dirty bit before handling the write request.
     2696                    //  If we don't need to set the Dirty bit, we request a SC transaction
     2697                    //  to CMD FSM and go to DCACHE_SC_WAIT state, that will return
     2698                    //  the response to the processor.
     2699                    //  We don't check a possible write hit in dcache, as the cache update
     2700                    //  is done by the coherence transaction induced by the SC...
    26612701                    else if ( ( m_dreq.type == iss_t::DATA_SC )
    26622702                        and not r_dcache_p0_valid.read() and not r_dcache_p1_valid.read() )
    26632703                    {
    2664                         if ( (r_dcache_ll_vaddr.read() != m_dreq.addr)
    2665                              or not r_dcache_ll_valid.read() )  // no valid registered LL
    2666                         {
     2704                        if ( (r_mmu_mode.read() & DATA_TLB_MASK )
     2705                              and not tlb_flags.d )                     // Dirty bit must be set
     2706                        {
     2707                            // The PTE physical address is obtained from the nline value (dtlb),
     2708                            // and the word index (virtual address)
     2709                            if ( tlb_flags.b )  // PTE1
     2710                            {
     2711                                r_dcache_dirty_paddr = (paddr_t)(tlb_nline*(m_dcache_words<<2)) |
     2712                                                       (paddr_t)((m_dreq.addr>>19) & 0x3c);
     2713                            }
     2714                            else                        // PTE2
     2715                            {
     2716                                r_dcache_dirty_paddr = (paddr_t)(tlb_nline*(m_dcache_words<<2)) |
     2717                                                       (paddr_t)((m_dreq.addr>>9) & 0x38);
     2718                            }
     2719                            r_dcache_fsm           = DCACHE_DIRTY_GET_PTE;
     2720                        }
     2721                        else                                    // SC request accepted
     2722                        {
    26672723#ifdef INSTRUMENTATION
    26682724m_cpt_data_sc++;
    26692725#endif
    2670                             m_drsp.valid        = true;
    2671                             m_drsp.rdata        = 1;
    2672                             r_dcache_ll_valid   = false;
    2673                         }
    2674                         else                                    // valid registered LL
    2675                         {
    2676                             if ( (r_mmu_mode.read() & DATA_TLB_MASK )
    2677                                   and not tlb_flags.d )                 // Dirty bit must be set
     2726                            // prepare llsc local table access
     2727                            table_in.cmd       = LLSCLocalTable::SC_CMD ;
     2728                            table_in.address   = paddr;
     2729                            // access the table
     2730                            r_llsc_table.exec(table_in, table_out)  ;
     2731                            llsc_local_table_access_done = true;
     2732                            // test if the table is done
     2733                            if(!table_out.done)
    26782734                            {
    2679                                 // The PTE physical address is obtained from the nline value (dtlb),
    2680                                 // and the word index (virtual address)
    2681                                 if ( tlb_flags.b )      // PTE1
    2682                                 {
    2683                                     r_dcache_dirty_paddr = (paddr_t)(tlb_nline*(m_dcache_words<<2)) |
    2684                                                            (paddr_t)((m_dreq.addr>>19) & 0x3c);
    2685                                 }
    2686                                 else                    // PTE2
    2687                                 {
    2688                                     r_dcache_dirty_paddr = (paddr_t)(tlb_nline*(m_dcache_words<<2)) |
    2689                                                            (paddr_t)((m_dreq.addr>>9) & 0x38);
    2690                                 }
    2691                                 r_dcache_fsm           = DCACHE_DIRTY_GET_PTE;
     2735                                r_dcache_p0_valid     = false;
     2736                                break;
    26922737                            }
    2693                             else                                        // SC request accepted
     2738                            // test for a local fail
     2739                            if(table_out.hit)
    26942740                            {
    2695 #ifdef INSTRUMENTATION
    2696 m_cpt_data_sc++;
    2697 #endif
    2698      
    2699                                 r_dcache_vci_paddr  = paddr;
    2700                                 r_dcache_vci_sc_req = true;
    2701                                 r_dcache_vci_sc_old = r_dcache_ll_data.read();
    2702                                 r_dcache_vci_sc_new = m_dreq.wdata;
    2703                                 r_dcache_ll_valid   = false;
    2704                                 r_dcache_fsm        = DCACHE_SC_WAIT;
     2741                                // request an SC CMD and go to DCACHE_SC_WAIT state
     2742                                r_sc_key             = table_out.key;
     2743                                r_dcache_vci_paddr   = paddr;
     2744                                r_dcache_vci_sc_req  = true;
     2745                                r_dcache_vci_sc_data = m_dreq.wdata;
     2746                                r_dcache_fsm         = DCACHE_SC_WAIT;
     2747                            }
     2748                            else // local fail
     2749                            {
     2750                                    m_drsp.valid = true;
     2751                                    m_drsp.rdata = 0x1;
    27052752                            }
    27062753                        }
     
    29843031            {
    29853032                pt_updt                = true;
    2986                 r_dcache_vci_sc_old    = pte;
    2987                 r_dcache_vci_sc_new    = pte | PTE_L_MASK;
     3033                r_dcache_vci_cas_old    = pte;
     3034                r_dcache_vci_cas_new    = pte | PTE_L_MASK;
    29883035                pte                    = pte | PTE_L_MASK;
    29893036                r_dcache_tlb_pte_flags = pte;
     
    29953042            {
    29963043                pt_updt                = true;
    2997                 r_dcache_vci_sc_old    = pte;
    2998                 r_dcache_vci_sc_new    = pte | PTE_R_MASK;
     3044                r_dcache_vci_cas_old    = pte;
     3045                r_dcache_vci_cas_new    = pte | PTE_R_MASK;
    29993046                pte                    = pte | PTE_R_MASK;
    30003047                r_dcache_tlb_pte_flags = pte;
     
    32193266            {
    32203267                pt_updt                = true;
    3221                 r_dcache_vci_sc_old    = pte_flags;
    3222                 r_dcache_vci_sc_new    = pte_flags | PTE_L_MASK;
     3268                r_dcache_vci_cas_old    = pte_flags;
     3269                r_dcache_vci_cas_new    = pte_flags | PTE_L_MASK;
    32233270                pte_flags              = pte_flags | PTE_L_MASK;
    32243271                        r_dcache_tlb_pte_flags = pte_flags;
     
    32303277            {
    32313278                pt_updt                = true;
    3232                 r_dcache_vci_sc_old    = pte_flags;
    3233                 r_dcache_vci_sc_new    = pte_flags | PTE_R_MASK;
     3279                r_dcache_vci_cas_old    = pte_flags;
     3280                r_dcache_vci_cas_new    = pte_flags | PTE_R_MASK;
    32343281                pte_flags              = pte_flags | PTE_R_MASK;
    32353282                        r_dcache_tlb_pte_flags = pte_flags;
     
    33113358}
    33123359#endif
    3313         // r_dcache_vci_sc_old & r_dcache_vci_sc_new registers are already set
    3314         r_dcache_vci_paddr   = r_dcache_tlb_paddr.read();
    3315         r_dcache_vci_sc_req  = true;
     3360        // r_dcache_vci_cas_old & r_dcache_vci_cas_new registers are already set
     3361        r_dcache_vci_paddr = r_dcache_tlb_paddr.read();
     3362        // prepare llsc local table access
     3363        table_in.cmd       = LLSCLocalTable::SW_CMD;
     3364        table_in.address   = r_dcache_tlb_paddr.read();
     3365        // access the table
     3366        r_llsc_table.exec(table_in, table_out);
     3367        llsc_local_table_access_done = true;
     3368        // test if the table is done
     3369        if(!table_out.done)
     3370            break;
     3371        // request a CAS CMD and go to DCACHE_TLB_LR_WAIT state
     3372        r_dcache_vci_cas_req = true;
    33163373        r_dcache_fsm         = DCACHE_TLB_LR_WAIT;
    33173374        break;
     
    39213978            r_mmu_dbvar          = m_dreq.addr;
    39223979            r_vci_rsp_data_error = false;
    3923             m_drsp.error           = true;
    3924             m_drsp.valid           = true;
     3980            m_drsp.error         = true;
     3981            m_drsp.valid         = true;
    39253982            r_dcache_fsm         = DCACHE_IDLE;
    39263983            break;
     
    39353992            if ( m_dreq.valid and (m_dreq.addr == r_dcache_p0_vaddr.read()) )
    39363993            {
    3937                     m_drsp.valid          = true;
    3938                     m_drsp.rdata          = r_vci_rsp_fifo_dcache.read();
    3939 
    3940                 // makes reservation in case of LL
    3941                 if ( m_dreq.type == iss_t::DATA_LL )
    3942                 {
    3943                     r_dcache_ll_valid = true;
    3944                     r_dcache_ll_data  = r_vci_rsp_fifo_dcache.read();
    3945                     r_dcache_ll_vaddr = m_dreq.addr;
    3946                 }
     3994                    m_drsp.valid        = true;
     3995                    m_drsp.rdata        = r_vci_rsp_fifo_dcache.read();
    39473996            }
    39483997            }   
    39493998        break;
    39503999    }
    3951     ////////////////////
    3952     case DCACHE_SC_WAIT:        // waiting VCI response after a processor SC request
     4000    /////////////////////
     4001    case DCACHE_LL_WAIT:
    39534002    {
    39544003        // external coherence request
     
    39604009        }
    39614010
    3962         if ( r_vci_rsp_data_error.read() )              // bus error
     4011        if ( r_vci_rsp_data_error.read() )      // bus error
    39634012        {
    39644013            r_mmu_detr           = MMU_READ_DATA_ILLEGAL_ACCESS;
     
    39704019            break;
    39714020        }
    3972         else if ( r_vci_rsp_fifo_dcache.rok() )         // response available
    3973         {
    3974             vci_rsp_fifo_dcache_get = true;     
    3975             m_drsp.valid            = true;
     4021            else if ( r_vci_rsp_fifo_dcache.rok() )     // data available
     4022            {
     4023            // consume data
     4024            vci_rsp_fifo_dcache_get = true;
     4025            if(r_dcache_ll_rsp_count.read() == 0) //first flit
     4026            {
     4027                //access table
     4028                table_in.cmd    = LLSCLocalTable::LL_RSP    ;
     4029                table_in.index  = 0;//p_vci_ini_d.rtrdid.read() ; // TODO use this ?
     4030                table_in.key    = r_vci_rsp_fifo_dcache.read();
     4031                r_llsc_table.exec(table_in, table_out);
     4032                llsc_local_table_access_done = true;
     4033                r_dcache_ll_rsp_count = r_dcache_ll_rsp_count.read() + 1 ;
     4034            }
     4035            else //last flit
     4036            {
     4037                // acknowledge the processor request if it has not been modified
     4038                if ( m_dreq.valid and (m_dreq.addr == r_dcache_p0_vaddr.read()) )
     4039                {
     4040                    m_drsp.valid        = true;
     4041                    m_drsp.rdata        = r_vci_rsp_fifo_dcache.read();
     4042                }
     4043                r_dcache_fsm = DCACHE_IDLE;
     4044            }
     4045            }
     4046        break;
     4047    }
     4048    ////////////////////
     4049    case DCACHE_SC_WAIT:        // waiting VCI response after a processor SC request
     4050    {
     4051        // external coherence request
     4052        if ( r_tgt_dcache_req.read() )
     4053        {
     4054            r_dcache_fsm_cc_save = r_dcache_fsm;
     4055            r_dcache_fsm         = DCACHE_CC_CHECK;
     4056            break;
     4057        }
     4058
     4059        if ( r_vci_rsp_data_error.read() )              // bus error
     4060        {
     4061            r_mmu_detr           = MMU_READ_DATA_ILLEGAL_ACCESS;
     4062            r_mmu_dbvar          = m_dreq.addr;
     4063            r_vci_rsp_data_error = false;
     4064            m_drsp.error         = true;
     4065            m_drsp.valid         = true;
     4066            r_dcache_fsm         = DCACHE_IDLE;
     4067            break;
     4068        }
     4069            else if ( r_vci_rsp_fifo_dcache.rok() ) // response available
     4070            {
     4071            // consume response
     4072            vci_rsp_fifo_dcache_get = true;
     4073            m_drsp.valid            = true;
    39764074            m_drsp.rdata            = r_vci_rsp_fifo_dcache.read();
    39774075            r_dcache_fsm            = DCACHE_IDLE;
    3978         }       
     4076            }   
    39794077        break;
    39804078    }
     
    40024100        assert( hit and "error in DCACHE_DIRTY_TLB_SET: the PTE should be in dcache" );
    40034101
    4004         // request sc transaction to CMD_FSM
     4102        // request CAS transaction to CMD_FSM
    40054103        r_dcache_dirty_way  = way;
    40064104        r_dcache_dirty_set  = set;
    4007         r_dcache_vci_sc_req = true;
     4105        // prepare llsc local table access
     4106        table_in.cmd       = LLSCLocalTable::SW_CMD;
     4107        table_in.address   = r_dcache_dirty_paddr.read();
     4108        // access the table
     4109        r_llsc_table.exec(table_in, table_out);
     4110        llsc_local_table_access_done = true;
     4111        // test if the table is done
     4112        if(!table_out.done)
     4113            break;
     4114        // request a CAS CMD and go to DCACHE_DIRTY_WAIT state
     4115        r_dcache_vci_cas_req = true;
    40084116        r_dcache_vci_paddr  = r_dcache_dirty_paddr.read();
    4009         r_dcache_vci_sc_old = pte;
    4010         r_dcache_vci_sc_new = pte | PTE_D_MASK;
     4117        r_dcache_vci_cas_old = pte;
     4118        r_dcache_vci_cas_new = pte | PTE_D_MASK;
    40114119        r_dcache_fsm        = DCACHE_DIRTY_WAIT;
    40124120
     
    40414149        if ( r_vci_rsp_data_error.read() )      // bus error
    40424150        {
    4043             std::cout << "BUS ERROR in DCACHE_DIRTY_SC_WAIT state" << std::endl;
     4151            std::cout << "BUS ERROR in DCACHE_DIRTY_WAIT state" << std::endl;
    40444152            std::cout << "This should not happen in this state" << std::endl;
    40454153            exit(0);
     
    40534161if ( m_debug_dcache_fsm )
    40544162{
    4055     std::cout << "  <PROC " << name() << ".DCACHE_DIRTY_SC_WAIT> SC completed" << std::endl;
     4163    std::cout << "  <PROC " << name() << ".DCACHE_DIRTY_WAIT> SC completed" << std::endl;
    40564164}
    40574165#endif
     
    43034411    }   
    43044412    } // end switch r_dcache_fsm
     4413    // perform a NOP access the the local llsc table if necessary
     4414    if(llsc_local_table_access_done == false)
     4415    {
     4416        table_in.cmd = LLSCLocalTable::NOP;
     4417        r_llsc_table.exec(table_in, table_out);
     4418    }
    43054419
    43064420    ///////////////// wbuf update //////////////////////////////////////////////////////
     
    43474461    // - r_dcache_vci_miss_req (reset)
    43484462    // - r_dcache_vci_unc_req (reset)
    4349     // - r_dcache_vci_sc_req (reset)
     4463    // - r_dcache_vci_ll_req (reset)
     4464    // - r_dcache_vci_sc_req (reset in case of local sc fail)
     4465    // - r_dcache_vci_cas_req (reset)
    43504466    //
    43514467    // This FSM handles requests from both the DCACHE FSM & the ICACHE FSM.
    4352     // There is 6 request types, with the following priorities :
     4468    // There are 8 request types, with the following priorities :
    43534469    // 1 - Data Read Miss         : r_dcache_vci_miss_req and miss in the write buffer
    43544470    // 2 - Data Read Uncachable   : r_dcache_vci_unc_req 
     
    43564472    // 4 - Instruction Uncachable : r_icache_unc_req
    43574473    // 5 - Data Write             : r_wbuf.rok()     
    4358     // 6 - Data Store Conditionnal: r_dcache_vci_sc_req
     4474    // 6 - Data Linked Load       : r_dcache_vci_ll_req
     4475    // 7 - Data Store Conditionnal: r_dcache_vci_sc_req
     4476    // 8 - Compare And Swap       : r_dcache_vci_cas_req
    43594477    //
    43604478    // As we want to support several simultaneous VCI transactions, the VCI_CMD_FSM
     
    44304548//                m_length_write_transaction += (wbuf_max-wbuf_min+1);
    44314549            }
    4432             // 6 - Data Store Conditionnal
     4550            // 6 - Data Linked Load
     4551            // must check that all write transaction are completed
     4552            else if ( r_dcache_vci_ll_req.read() && r_wbuf.miss(r_dcache_vci_paddr.read()))
     4553            {
     4554                r_dcache_vci_ll_req = false;
     4555                r_vci_cmd_fsm       = CMD_DATA_LL;
     4556//              r_vci_cmd_cpt       = 0;
     4557//              m_cpt_sc_transaction++;
     4558            }
     4559            // 7 - Data Store Conditionnal
     4560            // should check that all write transaction are completed ?
    44334561            else if ( r_dcache_vci_sc_req.read() )
    44344562            {
    4435                 r_vci_cmd_fsm       = CMD_DATA_CAS;
    44364563                r_dcache_vci_sc_req = false;
    4437                 r_vci_cmd_cpt       = 0;
    4438 //                m_cpt_sc_transaction++;
     4564                r_vci_cmd_cpt  = 0;
     4565                r_vci_cmd_fsm  = CMD_DATA_SC;
     4566//              m_cpt_sc_transaction++;
     4567            }
     4568            // 8 - Compare And Swap
     4569            // should check that all write transaction are completed ?
     4570            else if ( r_dcache_vci_cas_req.read() )
     4571            {
     4572                r_vci_cmd_fsm        = CMD_DATA_CAS;
     4573                r_dcache_vci_cas_req = false;
     4574                r_vci_cmd_cpt        = 0;
     4575//              m_cpt_sc_transaction++;
    44394576            }
    44404577            break;
     
    44564593        }
    44574594        /////////////////
     4595        case CMD_DATA_SC:
    44584596        case CMD_DATA_CAS:
    44594597        {
    4460             // The SC VCI command contains two flits
     4598            // The CAS and SC VCI commands contain two flits
    44614599            if ( p_vci_ini_d.cmdack.read() )
    44624600            {
     
    44714609        case CMD_DATA_MISS:
    44724610        case CMD_DATA_UNC:
     4611        case CMD_DATA_LL:
    44734612        {
    44744613            // all read VCI commands contain one single flit
     
    44874626    // - r_vci_rsp_ins_error (set)
    44884627    // - r_vci_rsp_cpt
     4628    // - r_dcache_vci_sc_req (reset when SC response recieved)
    44894629    //
    44904630    // As the VCI_RSP and VCI_CMD are fully desynchronized to support several
     
    45404680            else if ( (p_vci_ini_d.rpktid.read() & 0x7) ==  TYPE_LL             )
    45414681            {
    4542                 assert(false and "TODO ! LL NOT IMPLEMENTED YET"); //TODO
    4543                 //r_vci_rsp_fsm = RSP_DATA_UNC;
     4682                r_vci_rsp_fsm = RSP_DATA_LL;
    45444683            }
    45454684            else if ( (p_vci_ini_d.rpktid.read() & 0x7) == TYPE_SC             )
    45464685            {
    4547                 assert(false and "TODO ! SC NOT IMPLEMENTED YET"); //TODO
    4548                 //r_vci_rsp_fsm = RSP_DATA_UNC;
     4686                r_vci_rsp_fsm = RSP_DATA_UNC;
    45494687            }
    45504688            else
     
    46704808        }
    46714809        ////////////////////
     4810        case RSP_DATA_LL:
     4811        {
     4812            if ( p_vci_ini_d.rspval.read() )
     4813            {
     4814                if ( (p_vci_ini_d.rerror.read()&0x1) != 0 )  // error reported
     4815                {
     4816                    r_vci_rsp_data_error = true;
     4817                    r_vci_rsp_fsm = RSP_IDLE;
     4818                }
     4819                if (r_vci_rsp_cpt.read() == 0) //first flit
     4820                {
     4821                    if(r_vci_rsp_fifo_dcache.wok())
     4822                    {
     4823                        assert(!p_vci_ini_d.reop.read() &&
     4824                            "illegal VCI response packet for LL");
     4825                        vci_rsp_fifo_dcache_put  = true;
     4826                        vci_rsp_fifo_dcache_data = p_vci_ini_d.rdata.read();
     4827                        r_vci_rsp_cpt            = r_vci_rsp_cpt.read() + 1;
     4828                    }
     4829                    break;
     4830                }
     4831                else // last flit
     4832                {
     4833                    if(r_vci_rsp_fifo_dcache.wok())
     4834                    {
     4835                        assert(p_vci_ini_d.reop.read() &&
     4836                            "illegal VCI response packet for LL");
     4837                        vci_rsp_fifo_dcache_put  = true;
     4838                        vci_rsp_fifo_dcache_data = p_vci_ini_d.rdata.read();
     4839                        r_vci_rsp_fsm            = RSP_IDLE;
     4840                    }
     4841                    break;
     4842                }
     4843            }
     4844            break;
     4845        }
     4846        ////////////////////
    46724847        case RSP_DATA_WRITE:
    46734848        {
     
    46784853
    46794854                r_vci_rsp_fsm = RSP_IDLE;
    4680                 uint32_t   wbuf_index = p_vci_ini_d.rtrdid.read() - (1<<(vci_param::T-1));
     4855                uint32_t   wbuf_index = p_vci_ini_d.rtrdid.read();
    46814856                bool       cacheable  = r_wbuf.completed(wbuf_index);
    46824857                if ( not cacheable ) r_dcache_pending_unc_write = false;
     
    48144989                                 vci_rsp_fifo_dcache_put,
    48154990                                 vci_rsp_fifo_dcache_data);
     4991
     4992    #undef LLSCLocalTable
    48164993} // end transition()
    48174994
     
    49515128        p_vci_ini_d.wdata   = r_wbuf.getData(r_vci_cmd_cpt.read());
    49525129        p_vci_ini_d.be      = r_wbuf.getBe(r_vci_cmd_cpt.read());
    4953         p_vci_ini_d.trdid   = r_wbuf.getIndex() + (1<<(vci_param::T-1));
     5130        p_vci_ini_d.trdid   = r_wbuf.getIndex();
    49545131        p_vci_ini_d.pktid   = TYPE_WRITE;
    49555132        p_vci_ini_d.plen    = (r_vci_cmd_max.read() - r_vci_cmd_min.read() + 1) << 2;
     
    49585135        break;
    49595136
     5137    case CMD_DATA_LL:
     5138        p_vci_ini_d.cmdval  = true;
     5139        p_vci_ini_d.address = r_dcache_vci_paddr.read() & ~0x3;
     5140        p_vci_ini_d.wdata   = 0;
     5141        p_vci_ini_d.be      = 0xF;
     5142        p_vci_ini_d.trdid   = 0;    //TODO local table index
     5143        p_vci_ini_d.pktid   = TYPE_LL;
     5144        p_vci_ini_d.plen    = 8;
     5145        p_vci_ini_d.cmd     = vci_param::CMD_LOCKED_READ;
     5146        p_vci_ini_d.eop     = true;
     5147        break;
     5148
     5149    case CMD_DATA_SC:
     5150        p_vci_ini_d.cmdval  = true;
     5151        p_vci_ini_d.address = r_dcache_vci_paddr.read() & ~0x3;
     5152        if ( r_vci_cmd_cpt.read() == 0 ) p_vci_ini_d.wdata = r_sc_key.read();
     5153        else                             p_vci_ini_d.wdata = r_dcache_vci_sc_data.read();
     5154        p_vci_ini_d.be      = 0xF;
     5155        p_vci_ini_d.trdid   = 0;
     5156        p_vci_ini_d.pktid   = TYPE_SC;
     5157        p_vci_ini_d.plen    = 8;
     5158        p_vci_ini_d.cmd     = vci_param::CMD_NOP;
     5159        p_vci_ini_d.eop     = (r_vci_cmd_cpt.read() == 1);
     5160        break;     
     5161
    49605162    case CMD_DATA_CAS:
    49615163        p_vci_ini_d.cmdval  = true;
    49625164        p_vci_ini_d.address = r_dcache_vci_paddr.read() & ~0x3;
    4963         if ( r_vci_cmd_cpt.read() == 0 ) p_vci_ini_d.wdata = r_dcache_vci_sc_old.read();
    4964         else                             p_vci_ini_d.wdata = r_dcache_vci_sc_new.read();
     5165        if ( r_vci_cmd_cpt.read() == 0 ) p_vci_ini_d.wdata = r_dcache_vci_cas_old.read();
     5166        else                             p_vci_ini_d.wdata = r_dcache_vci_cas_new.read();
    49655167        p_vci_ini_d.be      = 0xF;
    49665168        p_vci_ini_d.trdid   = 0;
     
    49835185        case RSP_DATA_MISS  : p_vci_ini_d.rspack = r_vci_rsp_fifo_dcache.wok(); break;
    49845186        case RSP_DATA_UNC   : p_vci_ini_d.rspack = r_vci_rsp_fifo_dcache.wok(); break;
     5187        case RSP_DATA_LL    : p_vci_ini_d.rspack = r_vci_rsp_fifo_dcache.wok(); break;
    49855188        case RSP_IDLE       : p_vci_ini_d.rspack = false; break;
    49865189    } // end switch r_vci_rsp_fsm
     
    50515254
    50525255// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
    5053 
    5054 
    5055 
    5056 
    5057 
    5058 
    5059 
    5060 
    5061 
    5062 
  • trunk/modules/vci_mem_cache_v4/caba/metadata/vci_mem_cache_v4.sd

    r273 r291  
    2424            Uses('common:mapping_table'),
    2525            Uses('caba:generic_fifo'),
     26            Uses('caba:generic_llsc_global_table'),
    2627        ],
    2728
  • trunk/modules/vci_mem_cache_v4/caba/source/include/vci_mem_cache_v4.h

    r289 r291  
    5454#include "mapping_table.h"
    5555#include "int_tab.h"
     56#include "generic_llsc_global_table.h"
    5657#include "mem_cache_directory_v4.h"
    5758#include "xram_transaction_v4.h"
     
    422423      CacheData       m_cache_data;       // data array[set][way][word]
    423424      HeapDirectory   m_heap;             // heap for copies
     425      GenericLLSCGlobalTable
     426      <
     427        32  ,   // desired number of slots
     428        4096,   // number of processors in the system
     429        8000,   // registratioçn life span (in # of LL operations)
     430        typename vci_param::fast_addr_t // address type
     431      >
     432      m_llsc_table;       // ll/sc global registration table
    424433
    425434      // adress masks
     
    491500      sc_signal<size_t>   r_read_next_ptr;   // Next entry to point to
    492501      sc_signal<bool>     r_read_last_free;  // Last free entry
     502      sc_signal<typename vci_param::fast_addr_t>
     503                          r_read_ll_key;     // LL key returned by the llsc_global_table
    493504
    494505      // Buffer between READ fsm and IXR_CMD fsm (ask a missing cache line to XRAM)
     
    505516      sc_signal<size_t>   r_read_to_tgt_rsp_word;   // first word of the response
    506517      sc_signal<size_t>   r_read_to_tgt_rsp_length; // length of the response
     518      sc_signal<typename vci_param::fast_addr_t>
     519                          r_read_to_tgt_rsp_ll_key; // LL key returned by the llsc_global_table
    507520
    508521      ///////////////////////////////////////////////////////////////
     
    533546      sc_signal<size_t>   r_write_trt_index;  // index in Transaction Table
    534547      sc_signal<size_t>   r_write_upt_index;  // index in Update Table
     548      sc_signal<bool>     r_write_sc_fail;    // sc command failed
     549      sc_signal<bool>     r_write_pending_sc; // sc command pending in WRITE fsm
    535550
    536551      // Buffer between WRITE fsm and TGT_RSP fsm (acknowledge a write command from L1)
    537       sc_signal<bool>     r_write_to_tgt_rsp_req;   // valid request
    538       sc_signal<size_t>   r_write_to_tgt_rsp_srcid; // transaction srcid
    539       sc_signal<size_t>   r_write_to_tgt_rsp_trdid; // transaction trdid
    540       sc_signal<size_t>   r_write_to_tgt_rsp_pktid; // transaction pktid
     552      sc_signal<bool>     r_write_to_tgt_rsp_req;     // valid request
     553      sc_signal<size_t>   r_write_to_tgt_rsp_srcid;   // transaction srcid
     554      sc_signal<size_t>   r_write_to_tgt_rsp_trdid;   // transaction trdid
     555      sc_signal<size_t>   r_write_to_tgt_rsp_pktid;   // transaction pktid
     556      sc_signal<bool>     r_write_to_tgt_rsp_sc_fail; // sc command failed
    541557
    542558      // Buffer between WRITE fsm and IXR_CMD fsm (ask a missing cache line to XRAM)
     
    721737      sc_signal<size_t>   r_xram_rsp_to_tgt_rsp_length; // length of the response
    722738      sc_signal<bool>     r_xram_rsp_to_tgt_rsp_rerror; // send error to requester
     739      sc_signal<typename vci_param::fast_addr_t>
     740                          r_xram_rsp_to_tgt_rsp_ll_key; // LL key returned by the llsc_global_table
    723741
    724742      // Buffer between XRAM_RSP fsm and INIT_CMD fsm (Inval L1 Caches)
  • trunk/modules/vci_mem_cache_v4/caba/source/include/xram_transaction_v4.h

    r253 r291  
    3232    std::vector<be_t>   wdata_be;       // be for each data in the write buffer
    3333    bool                rerror;         // error returned by xram
     34    data_t              ll_key;         // LL key returned by the llsc_global_table
    3435
    3536    /////////////////////////////////////////////////////////////////////
     
    127128        wdata.assign(source.wdata.begin(),source.wdata.end()); 
    128129        rerror      = source.rerror;
     130        ll_key      = source.ll_key;
    129131    }
    130132
     
    325327    // - data : the data to write (in case of write)
    326328    // - data_be : the mask of the data to write (in case of write)
     329    // - ll_key  : the ll key (if any) returned by the llsc_global_table
    327330    /////////////////////////////////////////////////////////////////////
    328331    void set(const size_t index,
     
    336339            const size_t word_index,
    337340            const std::vector<be_t> &data_be,
    338             const std::vector<data_t> &data)
     341            const std::vector<data_t> &data,
     342            const data_t ll_key = 0)
    339343    {
    340344        assert( (index < size_tab)
     
    354358        tab[index].read_length      = read_length;
    355359        tab[index].word_index       = word_index;
     360        tab[index].ll_key           = ll_key;
    356361        for(size_t i=0; i<tab[index].wdata.size(); i++)
    357362        {
  • trunk/modules/vci_mem_cache_v4/caba/source/src/vci_mem_cache_v4.cpp

    r290 r291  
    293293    m_cache_data( nways, nsets, nwords ),
    294294    m_heap( m_heap_size ),
     295    m_llsc_table(),
    295296
    296297#define L2 soclib::common::uint32_log2
     
    511512              << " | " << ixr_rsp_fsm_str[r_ixr_rsp_fsm]
    512513              << " | " << xram_rsp_fsm_str[r_xram_rsp_fsm] << std::endl;
     514
     515              //m_llsc_table.print_trace();
     516
    513517}
    514518
     
    860864          assert(((p_vci_tgt.pktid.read() & 0x7) == 0x6) &&
    861865            "The type specified in the pktid field is incompatible with the LL CMD");
    862           assert(false && "TODO : LL not implemented"); //TODO
    863           //r_tgt_cmd_fsm = TGT_CMD_READ;
     866          r_tgt_cmd_fsm = TGT_CMD_READ;
    864867        }
    865868        else if ( p_vci_tgt.cmd.read() == vci_param::CMD_NOP )
     
    874877            "The type specified in the pktid field is incompatible with the NOP CMD");
    875878
    876           if(p_vci_tgt.pktid.read() == TYPE_CAS)
     879          if((p_vci_tgt.pktid.read() & 0x7) == TYPE_CAS)
    877880            r_tgt_cmd_fsm = TGT_CMD_CAS;
    878881          else // TYPE_SC
    879             assert(false && "TODO : SC not implemented"); //TODO
    880             //r_tgt_cmd_fsm = TGT_CMD_WRITE;
     882            r_tgt_cmd_fsm = TGT_CMD_WRITE;
    881883        }
    882884        else
     
    892894    //////////////////
    893895    case TGT_CMD_READ:
    894       if ((m_x[(vci_addr_t)p_vci_tgt.address.read()]+(p_vci_tgt.plen.read()>>2)) > 16)
     896      // This test checks that the read does not cross a cache line limit.
     897      // It must not be taken into account when dealing with an LL CMD.
     898      if (((m_x[(vci_addr_t)p_vci_tgt.address.read()]+(p_vci_tgt.plen.read()>>2)) > 16) && ( p_vci_tgt.cmd.read() != vci_param::CMD_LOCKED_READ ))
    895899      {
    896900        std::cout
     
    907911          << std::endl;
    908912        std::cout
    909           << " read command packets must contain one single flit"
     913          << " read or ll command packets must contain one single flit"
    910914          << std::endl;
    911915        exit(0);
     
    927931#endif
    928932        cmd_read_fifo_put = true;
    929         m_cpt_read++;
     933        if ( p_vci_tgt.cmd.read() == vci_param::CMD_LOCKED_READ )
     934          m_cpt_ll++;
     935        else
     936          m_cpt_read++;
    930937        r_tgt_cmd_fsm = TGT_CMD_IDLE;
    931938      }
     
    11391146  //    READ FSM
    11401147  ////////////////////////////////////////////////////////////////////////////////////
    1141   // The READ FSM controls the VCI read requests.
     1148  // The READ FSM controls the VCI read  and ll requests.
    11421149  // It takes the lock protecting the cache directory to check the cache line status:
    11431150  // - In case of HIT
     
    11741181            << " srcid = " << std::dec << m_cmd_read_srcid_fifo.read()
    11751182            << " / address = " << std::hex << m_cmd_read_addr_fifo.read()
     1183            << " / pktid = " << std::hex << m_cmd_read_pktid_fifo.read()
    11761184            << " / nwords = " << std::dec << m_cmd_read_length_fifo.read() << std::endl;
    11771185        }
     
    12111219        DirectoryEntry entry =
    12121220          m_cache_directory.read(m_cmd_read_addr_fifo.read(), way);
    1213 
     1221        if((m_cmd_read_pktid_fifo.read() & 0x7) == TYPE_LL) // access the global table ONLY when we have an LL cmd
     1222        {
     1223          r_read_ll_key   = m_llsc_table.ll(m_cmd_read_addr_fifo.read());
     1224        }
    12141225        r_read_is_cnt     = entry.is_cnt;
    12151226        r_read_dirty      = entry.dirty;
     
    12561267            << " / count = " <<std::dec << entry.count
    12571268            << " / is_cnt = " << entry.is_cnt << std::endl;
     1269            if((m_cmd_read_pktid_fifo.read() & 0x7) == TYPE_LL)
     1270            {
     1271              std::cout
     1272                << "  <MEMC " << name() << ".READ_DIR_LOCK> global_llsc_table LL access" << std::endl;
     1273            }
    12581274        }
    12591275#endif
     
    16041620        r_read_to_tgt_rsp_trdid  = m_cmd_read_trdid_fifo.read();
    16051621        r_read_to_tgt_rsp_pktid  = m_cmd_read_pktid_fifo.read();
    1606         cmd_read_fifo_get    = true;
    1607         r_read_to_tgt_rsp_req  = true;
    1608         r_read_fsm     = READ_IDLE;
     1622        r_read_to_tgt_rsp_ll_key = r_read_ll_key.read();
     1623        cmd_read_fifo_get        = true;
     1624        r_read_to_tgt_rsp_req    = true;
     1625        r_read_fsm               = READ_IDLE;
    16091626
    16101627#if DEBUG_MEMC_READ
     
    16731690            m_x[(vci_addr_t)(m_cmd_read_addr_fifo.read())],
    16741691            std::vector<be_t>(m_words,0),
    1675             std::vector<data_t>(m_words,0));
     1692            std::vector<data_t>(m_words,0),
     1693            r_read_ll_key.read());
    16761694#if DEBUG_MEMC_READ
    16771695        if( m_debug_read_fsm )
     
    17181736  //    WRITE FSM
    17191737  ///////////////////////////////////////////////////////////////////////////////////
    1720   // The WRITE FSM handles the write bursts sent by the processors.
     1738  // The WRITE FSM handles the write bursts and sc requests sent by the processors.
    17211739  // All addresses in a burst must be in the same cache line.
    17221740  // A complete write burst is consumed in the FIFO & copied to a local buffer.
     
    17281746  //   returned to the writing processor.
    17291747  //   If the data is cached by other processors, a coherence transaction must
    1730   //   be launched:
     1748  //   be launched (sc requests always require a coherence transaction):
    17311749  //   It is a multicast update if the line is not in counter mode, and the processor
    17321750  //   takes the lock protecting the Update Table (UPT) to register this transaction.
     
    17531771      if ( m_cmd_write_addr_fifo.rok() )
    17541772      {
    1755         m_cpt_write++;
    1756         m_cpt_write_cells++;
     1773        if((m_cmd_write_pktid_fifo.read() & 0x7) == TYPE_SC)
     1774          m_cpt_sc++;
     1775        else
     1776        {
     1777          m_cpt_write++;
     1778          m_cpt_write_cells++;
     1779        }
    17571780
    17581781        // consume a word in the FIFO & write it in the local buffer
    17591782        cmd_write_fifo_get  = true;
     1783        r_write_pending_sc  = false;
    17601784        size_t index        = m_x[(vci_addr_t)(m_cmd_write_addr_fifo.read())];
    17611785
     
    17751799        }
    17761800
    1777         if( m_cmd_write_eop_fifo.read() )
     1801        if( m_cmd_write_eop_fifo.read() || ((m_cmd_write_pktid_fifo.read() & 0x7)  == TYPE_SC) )
    17781802        {
    17791803          r_write_fsm = WRITE_DIR_REQ;
     
    18241848        // consume a word in the FIFO & write it in the local buffer
    18251849        cmd_write_fifo_get  = true;
     1850        r_write_pending_sc  = false;
    18261851        size_t index        = r_write_word_index.read() + r_write_word_count.read();
    18271852
     
    18441869      if ( r_alloc_dir_fsm.read() == ALLOC_DIR_WRITE )
    18451870      {
     1871        if(((r_write_pktid.read() & 0x7) == TYPE_SC) && not r_write_pending_sc.read()) // check for an SC command (and check that its second flit is not already consumed)
     1872        {
     1873          if ( m_cmd_write_addr_fifo.rok() )
     1874          {
     1875            size_t index    = m_x[(vci_addr_t)(r_write_address.read())];
     1876            bool sc_success = m_llsc_table.sc(r_write_address.read(),r_write_data[index].read());
     1877            r_write_sc_fail = !sc_success;
     1878
     1879            assert(m_cmd_write_eop_fifo.read() && "Error in VCI_MEM_CACHE : invalid packet format for SC command");
     1880            // consume a word in the FIFO & write it in the local buffer
     1881            cmd_write_fifo_get  = true;
     1882            r_write_pending_sc  = true;
     1883            index               = m_x[(vci_addr_t)(m_cmd_write_addr_fifo.read())];
     1884
     1885            r_write_address     = (addr_t)(m_cmd_write_addr_fifo.read());
     1886            r_write_word_index  = index;
     1887            r_write_word_count  = 1;
     1888            r_write_data[index] = m_cmd_write_data_fifo.read();
     1889            if (!sc_success)
     1890            {
     1891              r_write_fsm = WRITE_RSP;
     1892              break;
     1893            }
     1894          }
     1895          else break;
     1896        }
     1897        //else it is a TYPE_WRITE, need a simple sw access to the
     1898        // llsc_global_table
     1899        else
     1900        {
     1901          m_llsc_table.sw(r_write_address.read());
     1902        }
    18461903        r_write_fsm = WRITE_DIR_LOCK;
    18471904      }
     
    19051962            << " count = " << entry.count
    19061963            << " is_cnt = " << entry.is_cnt << std::endl;
     1964          if((r_write_pktid.read() & 0x7) == TYPE_SC)
     1965            std::cout << "  <MEMC " << name() << ".WRITE_DIR_LOCK> global_llsc_table SC access" << std::endl;
     1966          else
     1967            std::cout << "  <MEMC " << name() << ".WRITE_DIR_LOCK> global_llsc_table SW access" << std::endl;
    19071968        }
    19081969#endif
     
    19852046
    19862047      // no_update is true when there is no need for coherence transaction
    1987       bool no_update = (r_write_count.read()==0) || ( owner && (r_write_count.read()==1));
     2048      // (tests for sc requests)
     2049      bool no_update = ((r_write_count.read()==0) || ( owner && (r_write_count.read()==1) && (r_write_pktid.read() != TYPE_SC)));
    19882050
    19892051      // write data in the cache if no coherence transaction
     
    20042066      }
    20052067
    2006       if ( owner and not no_update )
     2068      if ( owner and not no_update and (r_write_pktid.read() != TYPE_SC))
    20072069      {
    20082070        r_write_count = r_write_count.read() - 1;
     
    21272189    case WRITE_UPT_REQ:
    21282190    {
    2129       // prepare the coherence ransaction for the INIT_CMD FSM
     2191      // prepare the coherence transaction for the INIT_CMD FSM
    21302192      // and write the first copy in the FIFO
    21312193      // send the request if only one copy
     
    21462208        for (size_t i=min ; i<max ; i++) r_write_to_init_cmd_data[i] = r_write_data[i];
    21472209
    2148         if( (r_write_copy.read() != r_write_srcid.read()) or
     2210        if( (r_write_copy.read() != r_write_srcid.read()) or (r_write_pktid.read() == TYPE_SC) or
    21492211#if L1_MULTI_CACHE
    21502212            (r_write_copy_cache.read() != r_write_pktid.read()) or
     
    21592221          write_to_init_cmd_fifo_cache_id= r_write_copy_cache.read();
    21602222#endif
    2161           if(r_write_count.read() == 1)
     2223          if(r_write_count.read() == 1 || ((r_write_count.read() == 0) && (r_write_pktid.read() == TYPE_SC)) )
    21622224          {
    21632225            r_write_fsm = WRITE_IDLE;
     
    22072269      bool dec_upt_counter;
    22082270
    2209       if( (entry.owner.srcid != r_write_srcid.read()) or
     2271      if(((entry.owner.srcid != r_write_srcid.read()) || (r_write_pktid.read() == TYPE_SC)) or
    22102272#if L1_MULTI_CACHE
    22112273          (entry.owner.cache_id != r_write_pktid.read()) or
    22122274#endif
    2213           entry.owner.inst)               // put te next srcid in the fifo
     2275          entry.owner.inst)             // put the next srcid in the fifo
    22142276      {
    22152277        dec_upt_counter                 = false;
     
    22992361      {
    23002362        // post the request to TGT_RSP_FSM
    2301         r_write_to_tgt_rsp_req   = true;
    2302         r_write_to_tgt_rsp_srcid = r_write_srcid.read();
    2303         r_write_to_tgt_rsp_trdid = r_write_trdid.read();
    2304         r_write_to_tgt_rsp_pktid = r_write_pktid.read();
     2363        r_write_to_tgt_rsp_req     = true;
     2364        r_write_to_tgt_rsp_srcid   = r_write_srcid.read();
     2365        r_write_to_tgt_rsp_trdid   = r_write_trdid.read();
     2366        r_write_to_tgt_rsp_pktid   = r_write_pktid.read();
     2367        r_write_to_tgt_rsp_sc_fail = r_write_sc_fail.read();
    23052368
    23062369        // try to get a new write request from the FIFO
    23072370        if ( m_cmd_write_addr_fifo.rok() )
    23082371        {
    2309           m_cpt_write++;
    2310           m_cpt_write_cells++;
     2372          if((m_cmd_write_pktid_fifo.read() & 0x7) == TYPE_SC)
     2373            m_cpt_sc++;
     2374          else
     2375          {
     2376            m_cpt_write++;
     2377            m_cpt_write_cells++;
     2378          }
    23112379
    23122380          // consume a word in the FIFO & write it in the local buffer
    23132381          cmd_write_fifo_get  = true;
     2382          r_write_pending_sc  = false;
    23142383          size_t index        = m_x[(vci_addr_t)(m_cmd_write_addr_fifo.read())];
    23152384
     
    23292398          }
    23302399
    2331           if( m_cmd_write_eop_fifo.read() )
     2400          if( m_cmd_write_eop_fifo.read() || ((m_cmd_write_pktid_fifo.read() & 0x7)  == TYPE_SC) )
    23322401          {
    23332402            r_write_fsm = WRITE_DIR_REQ;
     
    31913260            entry.lock    = false;
    31923261            entry.dirty   = dirty;
    3193             entry.tag   = r_xram_rsp_trt_buf.nline / m_sets;
     3262            entry.tag     = r_xram_rsp_trt_buf.nline / m_sets;
    31943263            entry.ptr     = 0;
    31953264            if(cached_read)
     
    33053374                r_xram_rsp_to_tgt_rsp_word   = r_xram_rsp_trt_buf.word_index;
    33063375                r_xram_rsp_to_tgt_rsp_length = r_xram_rsp_trt_buf.read_length;
     3376                r_xram_rsp_to_tgt_rsp_ll_key = r_xram_rsp_trt_buf.ll_key;
    33073377                r_xram_rsp_to_tgt_rsp_rerror = false;
    33083378                r_xram_rsp_to_tgt_rsp_req    = true;
     
    43714441        //////////////////////
    43724442        case CAS_DIR_HIT_WRITE:    // test if a CC transaction is required
    4373                                     // write data in cache if no CC request
    4374         {
     4443                                   // write data in cache if no CC request
     4444        {
     4445            // The CAS is a success => sw access to the llsc_global_table
     4446            m_llsc_table.sw(m_cmd_cas_addr_fifo.read());
     4447
    43754448            // test coherence request
    43764449            if(r_cas_count.read())   // replicated line
     
    44224495              << " / value = " << r_cas_wdata.read()
    44234496              << " / count = " << r_cas_count.read() << std::endl;
     4497    std::cout << "  <MEMC " << name() << ".CAS_DIR_HIT_WRITE> global_llsc_table SW access" << std::endl;
    44244498}
    44254499#endif
     
    63836457      case TGT_RSP_READ:
    63846458        p_vci_tgt.rspval   = true;
    6385         p_vci_tgt.rdata    = r_read_to_tgt_rsp_data[r_tgt_rsp_cpt.read()].read();
     6459        if( ((r_read_to_tgt_rsp_pktid.read() & 0x7) == TYPE_LL)
     6460            && (r_tgt_rsp_cpt.read() == (r_read_to_tgt_rsp_word.read()+r_read_to_tgt_rsp_length-1)) )
     6461          p_vci_tgt.rdata  = r_read_to_tgt_rsp_data[r_tgt_rsp_cpt.read()-1].read();
     6462        else if ((r_read_to_tgt_rsp_pktid.read() & 0x7) == TYPE_LL)
     6463          p_vci_tgt.rdata  = r_read_to_tgt_rsp_ll_key.read();
     6464        else
     6465          p_vci_tgt.rdata  = r_read_to_tgt_rsp_data[r_tgt_rsp_cpt.read()].read();
    63866466        p_vci_tgt.rsrcid   = r_read_to_tgt_rsp_srcid.read();
    63876467        p_vci_tgt.rtrdid   = r_read_to_tgt_rsp_trdid.read();
     
    63916471        break;
    63926472      case TGT_RSP_WRITE:
     6473        /*if( ((r_write_to_tgt_rsp_pktid.read() & 0x7) == TYPE_SC) )
     6474            {
     6475              std::cout << "SC RSP / rsrcid = " << r_write_to_tgt_rsp_srcid.read() << " / rdata = " << r_write_to_tgt_rsp_sc_fail.read() << std::endl;
     6476            }*/
    63936477        p_vci_tgt.rspval   = true;
    6394         p_vci_tgt.rdata    = 0;
     6478        if( ((r_write_to_tgt_rsp_pktid.read() & 0x7) == TYPE_SC) && r_write_to_tgt_rsp_sc_fail.read() )
     6479          p_vci_tgt.rdata  = 1;
     6480        else
     6481          p_vci_tgt.rdata  = 0;
    63956482        p_vci_tgt.rsrcid   = r_write_to_tgt_rsp_srcid.read();
    63966483        p_vci_tgt.rtrdid   = r_write_to_tgt_rsp_trdid.read();
    63976484        p_vci_tgt.rpktid   = r_write_to_tgt_rsp_pktid.read();
    6398         p_vci_tgt.rerror   = 0x2 & ( (1 << vci_param::E) - 1);
     6485        //p_vci_tgt.rerror   = 0x2 & ( (1 << vci_param::E) - 1);
     6486        p_vci_tgt.rerror   = 0;
    63996487        p_vci_tgt.reop     = true;
    64006488        break;
     
    64196507      case TGT_RSP_XRAM:
    64206508        p_vci_tgt.rspval   = true;
    6421         p_vci_tgt.rdata    = r_xram_rsp_to_tgt_rsp_data[r_tgt_rsp_cpt.read()].read();
     6509        if( ((r_xram_rsp_to_tgt_rsp_pktid.read() & 0x7) == TYPE_LL)
     6510            && (r_tgt_rsp_cpt.read() == (r_xram_rsp_to_tgt_rsp_word.read()+r_xram_rsp_to_tgt_rsp_length-1)) )
     6511          p_vci_tgt.rdata  = r_xram_rsp_to_tgt_rsp_ll_key.read();
     6512        else
     6513          p_vci_tgt.rdata  = r_xram_rsp_to_tgt_rsp_data[r_tgt_rsp_cpt.read()].read();
    64226514        p_vci_tgt.rsrcid   = r_xram_rsp_to_tgt_rsp_srcid.read();
    64236515        p_vci_tgt.rtrdid   = r_xram_rsp_to_tgt_rsp_trdid.read();
     
    64306522      case TGT_RSP_INIT:
    64316523        p_vci_tgt.rspval   = true;
    6432         p_vci_tgt.rdata    = 0;
     6524        p_vci_tgt.rdata    = 0; // Can be a CAS or SC rsp
    64336525        p_vci_tgt.rsrcid   = r_init_rsp_to_tgt_rsp_srcid.read();
    64346526        p_vci_tgt.rtrdid   = r_init_rsp_to_tgt_rsp_trdid.read();
    64356527        p_vci_tgt.rpktid   = r_init_rsp_to_tgt_rsp_pktid.read();
    6436         p_vci_tgt.rerror   = 0; // Can be a CAS rsp
     6528        p_vci_tgt.rerror   = 0;
    64376529        p_vci_tgt.reop     = true;
    64386530        break;
Note: See TracChangeset for help on using the changeset viewer.