Index: /trunk/lib/generic_llsc_global_table/include/generic_llsc_global_table.h
===================================================================
--- /trunk/lib/generic_llsc_global_table/include/generic_llsc_global_table.h	(revision 526)
+++ /trunk/lib/generic_llsc_global_table/include/generic_llsc_global_table.h	(revision 527)
@@ -28,6 +28,4 @@
 #define SOCLIB_GENERIC_LLSC_GLOBAL_TABLE_H
 
-#include <systemc>
-#include <arithmetics.h>
 #include <cassert>
 #include <cstring>
@@ -35,4 +33,5 @@
 #include <iostream>
 #include <iomanip>
+#include <stdint.h>
 
 namespace soclib
@@ -70,15 +69,16 @@
 
     uint32_t                    r_next_key        ; // value of the next key
-    sc_dt::sc_uint<nb_slots>    r_block_mask      ; // mask for the slots blocks
-    sc_dt::sc_uint<nb_slots>    r_last_counter    ; // mask for the slots blocks
+    uint64_t                    r_block_mask      ; // mask for the slots blocks
+    uint64_t                    r_last_counter    ; // mask for the slots blocks
     size_t                      r_write_ptr       ; // index of next slot to replace
     size_t                      r_last_empty      ; // index of last empty slot used
 
-    uint32_t                    m_cpt_evic        ; // number of eviction in the table
-    uint32_t                    m_cpt_ll          ; // number of ll accesses to the table
-    uint32_t                    m_cpt_ll_update   ; // number of ll accesses to the table that trigger an update TODO check that
-    uint32_t                    m_cpt_sc          ; // number of sc accesses to the table
-    uint32_t                    m_cpt_sc_success  ; // number of sc accesses to the table that are successful
-    uint32_t                    m_cpt_sw          ; // number of sw accesses to the table
+    mutable uint32_t            m_cpt_evic        ; // number of eviction in the table
+    mutable uint32_t            m_cpt_ll          ; // number of ll accesses to the table
+    mutable uint32_t            m_cpt_ll_update   ; // number of ll accesses to the table that trigger an update TODO check that
+    mutable uint32_t            m_cpt_sc          ; // number of sc accesses to the table
+    mutable uint32_t            m_cpt_sc_success  ; // number of sc accesses to the table that are successful
+    mutable uint32_t            m_cpt_check       ; // number of check accesses to the table
+    mutable uint32_t            m_cpt_sw          ; // number of sw accesses to the table
 
     ////////////////////////////////////////////////////////////////////////////
@@ -121,6 +121,6 @@
     //  This is done by updating the value of r_write_ptr
     {
-        sc_dt::sc_uint<nb_slots> new_counter;
-        sc_dt::sc_uint<nb_slots> xor_counter;
+        uint64_t new_counter;
+        uint64_t xor_counter;
 
         new_counter = newCounter(r_block_mask, r_last_counter);
@@ -129,5 +129,5 @@
         for (size_t i = nb_slots - 1; i >= 0; --i)
         {
-            if(xor_counter[i])
+            if(xor_counter & (1 << i))
             {
                 r_write_ptr = i;
@@ -140,9 +140,8 @@
 
     ////////////////////////////////////////////////////////////////////////////
-    inline sc_dt::sc_uint<nb_slots> newCounter(const sc_dt::sc_uint<nb_slots>& mask,
-                                               const sc_dt::sc_uint<nb_slots>& counter)
+    inline uint64_t newCounter(const uint64_t& mask,
+                               const uint64_t& counter) const
     // This function generates the new counter //TODO comment more
     {
-        //
         return ((((~counter) & (counter << 1)) & mask) | (counter + 1));
     }
@@ -164,44 +163,44 @@
         {
             case 12:
-            r_block_mask = sc_dt::sc_uint<nb_slots>("0x000");
+            r_block_mask = (uint64_t)0x000ULL;
             break;
             case 16 :
-            r_block_mask = sc_dt::sc_uint<nb_slots>("0xA800");
+            r_block_mask = (uint64_t)0xA800ULL;
             break;
             case 20 :
-            r_block_mask = sc_dt::sc_uint<nb_slots>("0xD5500");
+            r_block_mask = (uint64_t)0xD5500ULL;
             break;
             case 24 :
-            r_block_mask = sc_dt::sc_uint<nb_slots>("0xDB5540");
+            r_block_mask = (uint64_t)0xDB5540ULL;
             break;
             case 28 :
-            r_block_mask = sc_dt::sc_uint<nb_slots>("0xEEDAAA0");
+            r_block_mask = (uint64_t)0xEEDAAA0ULL;
             break;
             case 32 :
-            r_block_mask = sc_dt::sc_uint<nb_slots>("0xF776D550");
+            r_block_mask = (uint64_t)0xF776D550ULL;
             break;
             case 36 :
-            r_block_mask = sc_dt::sc_uint<nb_slots>("0xFBDDDB550");
+            r_block_mask = (uint64_t)0xFBDDDB550ULL;
             break;
             case 40 :
-            r_block_mask = sc_dt::sc_uint<nb_slots>("0xFDF7BB6D50");
+            r_block_mask = (uint64_t)0xFDF7BB6D50ULL;
             break;
             case 44 :
-            r_block_mask = sc_dt::sc_uint<nb_slots>("0xFEFBDEEDAA8");
+            r_block_mask = (uint64_t)0xFEFBDEEDAA8ULL;
             break;
             case 48 :
-            r_block_mask = sc_dt::sc_uint<nb_slots>("0xFF7EFBDDDAA8");
+            r_block_mask = (uint64_t)0xFF7EFBDDDAA8ULL;
             break;
             case 52 :
-            r_block_mask = sc_dt::sc_uint<nb_slots>("0xFFBFBF7BBB6A8");
+            r_block_mask = (uint64_t)0xFFBFBF7BBB6A8ULL;
             break;
             case 56 :
-            r_block_mask = sc_dt::sc_uint<nb_slots>("0xFFDFEFDF7BB6A8");
+            r_block_mask = (uint64_t)0xFFDFEFDF7BB6A8ULL;
             break;
             case 60 :
-            r_block_mask = sc_dt::sc_uint<nb_slots>("0xFFF7FDFDF7BB6A8");
+            r_block_mask = (uint64_t)0xFFF7FDFDF7BB6A8ULL;
             break;
             case 64 :
-            r_block_mask = sc_dt::sc_uint<nb_slots>("0xFFFBFF7FBF7BB6A8");
+            r_block_mask = (uint64_t)0xFFFBFF7FBF7BB6A8ULL;
             break;
             default:
@@ -211,5 +210,5 @@
 
     ////////////////////////////////////////////////////////////////////////////
-    inline int nextEmptySlot()
+    inline int nextEmptySlot() const
     //  This function returns :
     //  - the position of the first next empty slot in the table
@@ -218,26 +217,15 @@
     //  - -1 if the table is full
     {
-        size_t i = r_last_empty;
-        do
-        {
-            // checking if current slot is empty
-            if(!r_val[i])
-            {
-                // updating last empty slot and returning its position
-                r_last_empty = i;
-                return i;
-            }
-            // selecting next slot
-            i = (i+1) % nb_slots;
-        }
-        // stop if all slots have been tested
-        while(i != r_last_empty);
-
-        // the table is full
+        uint64_t i; 
+        for(i = 0; i < nb_slots; i++)
+        {
+            if (!r_val[i]) return i;
+        }
+
         return -1;
     }
 
     ////////////////////////////////////////////////////////////////////////////
-    inline int hitAddr(const addr_t ad)
+    inline int hitAddr(const addr_t ad) const
     //  HIT on the address only
     //  This function takes an addr_t ad
@@ -259,5 +247,5 @@
 
     ////////////////////////////////////////////////////////////////////////////
-    inline int hitAddrKey(const addr_t ad, const uint32_t key)
+    inline int hitAddrKey(const addr_t ad, const uint32_t key) const
     //  HIT on the address AND the on the signature
     //  This function takes an addr_t ad and a uint32_t key
@@ -291,4 +279,5 @@
         m_cpt_sc            = 0;
         m_cpt_sc_success    = 0;
+        m_cpt_check         = 0;
         m_cpt_sw            = 0;
     }
@@ -301,8 +290,5 @@
     :   name(n)
     {
-        #define L2 soclib::common::uint32_log2
         assert(nb_procs > 1); 
-        assert((int)nb_slots >= L2(nb_procs));
-        #undef L2
         init();
         init_block_mask();
@@ -362,9 +348,14 @@
         if (pos >= 0)
         {
-            if(r_key[pos] - r_next_key > life_span)
-                return r_key[pos];
+            uint32_t absdiff = ( r_key[pos] > r_next_key) ?
+                                 r_key[pos] - r_next_key  :
+                                 r_next_key - r_key[pos];
+
+            if(absdiff < life_span) return r_key[pos];
+
             r_key[pos] = r_next_key;
             upNextKey();
             m_cpt_ll_update++;
+
             return r_key[pos];
         }
@@ -377,8 +368,10 @@
         if (pos == -1)
         {
+            //  update the victim slot for the next eviction
+            updateVictimSlot();
+
             //  get the position of the evicted registration
             pos = r_write_ptr;
-            //  update the victim slot for the next eviction
-            updateVictimSlot();
+
             // increment the eviction counter (for stats)
             m_cpt_evic++;
@@ -434,4 +427,16 @@
 
     ////////////////////////////////////////////////////////////////////////////
+    inline bool check(const addr_t ad, const uint32_t key) const
+    //  This method checks if there is a valid registration for the SC (ad &&
+    //  key)
+    //  The return value can be used to tell if the SC is atomic
+    {
+        // increment the check access counter (for stats)
+        m_cpt_check++;
+
+        return (hitAddrKey(ad, key) >= 0);
+    }
+
+    ////////////////////////////////////////////////////////////////////////////
     /*
     inline void sw(const addr_t ad)
@@ -489,25 +494,16 @@
     inline void print_trace(std::ostream& out = std::cout)
     {
-        out <<  " ___________________________________" << std::endl
-            <<  "| " << std::setw(33) << "generic_llsc_global_table" << " |" << std::endl
-            <<  "| " << std::setw(33) << name << " |" << std::endl
-            <<  " ===================================" << std::endl
-            <<  "| "
-            <<  std::setw(11) << "addr"   << " | "
-            <<  std::setw(11) << "key"    << " | "
-            <<  std::setw(5)  << "val"
-            << " |" << std::endl
-            <<  " -----------------------------------" << std::endl;
         for ( size_t i = 0; i < nb_slots ; i++ )
         {
-            out << "| "
-                << std::showbase
-                << std::setw(11) << std::setfill('0')   << std::hex       << r_addr[i]    << " | "
+            out << std::setw(3)   << std::setfill(' ') << std::dec << i
                 << std::noshowbase
-                << std::setw(11) << std::setfill('0')   << std::dec       << r_key[i]     << " | "
-                << std::setw(5)  << std::setfill(' ')   << std::boolalpha << r_val[i]     << " |" << std::endl ;
-        }
-        out <<  " -----------------------------------" << std::endl
-            << std::noshowbase << std::dec << std::endl ;
+                << " VLD_RX = "   << r_val[i]
+                << std::uppercase
+                << " ADR_RX = 0x" << std::setw(8) << std::setfill('0') << std::hex << (r_addr[i] >> 2)
+                << " SGN_RX = 0x" << std::setw(8) << std::setfill('0') << std::hex << r_key[i]
+                << std::endl;
+        }
+        out << "NEXT_SGN_RX = 0x" << std::setw(8) << std::setfill('0') << std::hex << r_next_key     << std::endl
+            << "CNT_RX = 0x"      << std::setw(8) << std::setfill('0') << std::hex << r_last_counter << std::endl;
     }
 
Index: /trunk/modules/vci_mem_cache/caba/source/include/vci_mem_cache.h
===================================================================
--- /trunk/modules/vci_mem_cache/caba/source/include/vci_mem_cache.h	(revision 526)
+++ /trunk/modules/vci_mem_cache/caba/source/include/vci_mem_cache.h	(revision 527)
@@ -702,5 +702,5 @@
       sc_signal<size_t>   r_write_upt_index;          // index in Update Table
       sc_signal<bool>     r_write_sc_fail;            // sc command failed
-      sc_signal<bool>     r_write_pending_sc;         // sc command pending
+      sc_signal<data_t>   r_write_sc_key;             // sc command key
 
       // Buffer between WRITE fsm and TGT_RSP fsm (acknowledge a write command from L1)
Index: /trunk/modules/vci_mem_cache/caba/source/src/vci_mem_cache.cpp
===================================================================
--- /trunk/modules/vci_mem_cache/caba/source/src/vci_mem_cache.cpp	(revision 526)
+++ /trunk/modules/vci_mem_cache/caba/source/src/vci_mem_cache.cpp	(revision 527)
@@ -2654,43 +2654,51 @@
             case WRITE_IDLE:  // copy first word of a write burst in local buffer
                 {
-                    if (m_cmd_write_addr_fifo.rok())
-                    {
-                        // consume a word in the FIFO & write it in the local buffer
-                        cmd_write_fifo_get  = true;
-                        size_t index        = m_x[(addr_t)(m_cmd_write_addr_fifo.read())];
-
-                        r_write_address     = (addr_t)(m_cmd_write_addr_fifo.read());
-                        r_write_word_index  = index;
-                        r_write_word_count  = 1;
-                        r_write_data[index] = m_cmd_write_data_fifo.read();
-                        r_write_srcid       = m_cmd_write_srcid_fifo.read();
-                        r_write_trdid       = m_cmd_write_trdid_fifo.read();
-                        r_write_pktid       = m_cmd_write_pktid_fifo.read();
-                        r_write_pending_sc  = false;
-
-                        // initialize the be field for all words
-                        for(size_t word=0 ; word<m_words ; word++)
-                        {
-                            if (word == index) r_write_be[word] = m_cmd_write_be_fifo.read();
-                            else              r_write_be[word] = 0x0;
-                        }
-
-                        if (m_cmd_write_eop_fifo.read() or ((m_cmd_write_pktid_fifo.read() & 0x7) == TYPE_SC))
-                        {
-                            r_write_fsm = WRITE_DIR_REQ;
-                        }
-                        else
-                        {
-                            r_write_fsm = WRITE_NEXT;
-                        }
+                    if (not m_cmd_write_addr_fifo.rok()) break;
+
+                    // consume a word in the FIFO & write it in the local buffer
+                    cmd_write_fifo_get  = true;
+                    size_t index        = m_x[(addr_t)(m_cmd_write_addr_fifo.read())];
+
+                    r_write_address     = (addr_t)(m_cmd_write_addr_fifo.read());
+                    r_write_word_index  = index;
+                    r_write_word_count  = 0;
+                    r_write_data[index] = m_cmd_write_data_fifo.read();
+                    r_write_srcid       = m_cmd_write_srcid_fifo.read();
+                    r_write_trdid       = m_cmd_write_trdid_fifo.read();
+                    r_write_pktid       = m_cmd_write_pktid_fifo.read();
+
+                    // if SC command, get the SC key
+                    if ((m_cmd_write_pktid_fifo.read() & 0x7) == TYPE_SC)
+                    {
+                        assert( not m_cmd_write_eop_fifo.read() &&
+                                "MEMC ERROR in WRITE_IDLE state: "
+                                "invalid packet format for SC command");
+
+                        r_write_sc_key = m_cmd_write_data_fifo.read();
+                    }
+
+                    // initialize the be field for all words
+                    for(size_t word=0 ; word<m_words ; word++)
+                    {
+                        if (word == index) r_write_be[word] = m_cmd_write_be_fifo.read();
+                        else               r_write_be[word] = 0x0;
+                    }
+
+                    if (m_cmd_write_eop_fifo.read())
+                    {
+                        r_write_fsm = WRITE_DIR_REQ;
+                    }
+                    else
+                    {
+                        r_write_fsm = WRITE_NEXT;
+                    }
 
 #if DEBUG_MEMC_WRITE
-                        if (m_debug)
-                            std::cout << "  <MEMC " << name() << " WRITE_IDLE> Write request "
-                                << " srcid = " << std::hex << m_cmd_write_srcid_fifo.read()
-                                << " / address = " << std::hex << m_cmd_write_addr_fifo.read()
-                                << " / data = " << m_cmd_write_data_fifo.read() << std::endl;
-#endif
-                    }
+                    if (m_debug)
+                        std::cout << "  <MEMC " << name() << " WRITE_IDLE> Write request "
+                            << " srcid = " << std::hex << m_cmd_write_srcid_fifo.read()
+                            << " / address = " << std::hex << m_cmd_write_addr_fifo.read()
+                            << " / data = " << m_cmd_write_data_fifo.read() << std::endl;
+#endif
                     break;
                 }
@@ -2698,80 +2706,79 @@
             case WRITE_NEXT:  // copy next word of a write burst in local buffer
                 {
-                    if (m_cmd_write_addr_fifo.rok())
-                    {
+                    if (not m_cmd_write_addr_fifo.rok()) break;
+
+                    // check that the next word is in the same cache line
+                    assert((m_nline[(addr_t)(r_write_address.read())] == 
+                            m_nline[(addr_t)(m_cmd_write_addr_fifo.read())]) &&
+                            "MEMC ERROR in WRITE_NEXT state: Illegal write burst");
+
+                    size_t index = m_x[(addr_t)(m_cmd_write_addr_fifo.read())];
+                    bool   is_sc = ((m_cmd_write_pktid_fifo.read() & 0x7) == TYPE_SC);
+
+                    // check that SC command has constant address
+                    assert( not is_sc or (index == r_write_word_index) &&
+                            "MEMC ERROR in WRITE_NEXT state: "
+                            "the address must be constant on a SC command");
+
+                    // check that SC command has two flits
+                    assert( not is_sc or m_cmd_write_eop_fifo.read() &&
+                            "MEMC ERROR in WRITE_NEXT state: "
+                            "invalid packet format for SC command");
+
+                    // consume a word in the FIFO & write it in the local buffer
+                    cmd_write_fifo_get  = true;
+
+                    r_write_be[index]   = m_cmd_write_be_fifo.read();
+                    r_write_data[index] = m_cmd_write_data_fifo.read();
+                    r_write_word_count  = r_write_word_count.read() + 1;
+
+                    if (m_cmd_write_eop_fifo.read()) r_write_fsm = WRITE_DIR_REQ;
 
 #if DEBUG_MEMC_WRITE
-                        if (m_debug)
-                            std::cout << "  <MEMC " << name()
-                                << " WRITE_NEXT> Write another word in local buffer"
-                                << std::endl;
-#endif
-
-                        // check that the next word is in the same cache line
-                        assert((m_nline[(addr_t)(r_write_address.read())] == 
-                                    m_nline[(addr_t)(m_cmd_write_addr_fifo.read())]) and
-                                "MEMC ERROR in WRITE_NEXT state: Illegal write burst");
-
-                        // consume a word in the FIFO & write it in the local buffer
-                        cmd_write_fifo_get  = true;
-                        size_t index        = r_write_word_index.read() + r_write_word_count.read();
-
-                        r_write_be[index]   = m_cmd_write_be_fifo.read();
-                        r_write_data[index] = m_cmd_write_data_fifo.read();
-                        r_write_word_count  = r_write_word_count.read() + 1;
-
-                        if (m_cmd_write_eop_fifo.read()) r_write_fsm = WRITE_DIR_REQ;
-                    }
+                    if (m_debug)
+                        std::cout << "  <MEMC " << name()
+                            << " WRITE_NEXT> Write another word in local buffer"
+                            << std::endl;
+#endif
                     break;
                 }
                 ///////////////////
-            case WRITE_DIR_REQ:    // Get the lock to the directory
-                // and access the llsc_global_table
-                {
-                    if (r_alloc_dir_fsm.read() == ALLOC_DIR_WRITE )
-                    {
-                        if (((r_write_pktid.read() & 0x7) == TYPE_SC) and not r_write_pending_sc.read())
-                        {
-                            // We enter here if it is a new SC command
-                            // If r_write_pending_sc is set the SC is not new and has already been tested
-
-                            if (not m_cmd_write_addr_fifo.rok()) break;
-
-                            assert( m_cmd_write_eop_fifo.read() and
-                                    "MEMC ERROR in WRITE_DIR_REQ state: invalid packet format for SC command");
-
-                            size_t index    = r_write_word_index.read();
-                            bool sc_success = m_llsc_table.sc(r_write_address.read(),
-                                    r_write_data[index].read());
-
-                            // consume a word in the FIFO & write it in the local buffer
-                            cmd_write_fifo_get  = true;
-                            r_write_data[index] = m_cmd_write_data_fifo.read();
-                            r_write_sc_fail     = not sc_success;
-                            r_write_pending_sc  = true;
-
-                            if (not sc_success) r_write_fsm = WRITE_RSP;
-                            else                r_write_fsm = WRITE_DIR_LOCK;
-                        }
-                        else
-                        {
-                            // We enter here if it is a SW command or an already tested SC command 
+            case WRITE_DIR_REQ: // Get the lock to the directory
+                                // and access the llsc_global_table
+                {
+                    if (r_alloc_dir_fsm.read() != ALLOC_DIR_WRITE ) break;
+
+                    if ((r_write_pktid.read() & 0x7) == TYPE_SC)
+                    {
+                        // test address and key match of the SC command on the
+                        // LL/SC table without removing reservation. The reservation
+                        // will be erased after in this FSM. 
+                        bool sc_success = m_llsc_table.check(r_write_address.read(),
+                                                             r_write_sc_key.read());
+
+                        r_write_sc_fail     = not sc_success;
+
+                        if (not sc_success) r_write_fsm = WRITE_RSP;
+                        else                r_write_fsm = WRITE_DIR_LOCK;
+                    }
+                    else
+                    {
+                        // write burst 
 #define L2 soclib::common::uint32_log2
-                            addr_t min = r_write_address.read();
-                            addr_t max = r_write_address.read() +
-                                       ((r_write_word_count.read()-1) << L2(vci_param_int::B));
+                        addr_t min = r_write_address.read();
+                        addr_t max = r_write_address.read() +
+                                    (r_write_word_count.read() << L2(vci_param_int::B));
 #undef L2
 
-                            m_llsc_table.sw(min, max);
-
-                            r_write_fsm = WRITE_DIR_LOCK;
-                        }
+                        m_llsc_table.sw(min, max);
+
+                        r_write_fsm = WRITE_DIR_LOCK;
+                    }
 
 #if DEBUG_MEMC_WRITE
-                        if (m_debug)
-                            std::cout << "  <MEMC " << name() << " WRITE_DIR_REQ> Requesting DIR lock "
-                                << std::endl;
-#endif
-                    }
+                    if (m_debug)
+                        std::cout << "  <MEMC " << name() << " WRITE_DIR_REQ> Requesting DIR lock "
+                            << std::endl;
+#endif
                     break;
                 }
@@ -2798,5 +2805,5 @@
 
                         if (entry.is_cnt and entry.count) r_write_fsm = WRITE_BC_DIR_READ;
-                        else                             r_write_fsm = WRITE_DIR_HIT;
+                        else                              r_write_fsm = WRITE_DIR_HIT;
                     }
                     else  // miss
@@ -2851,10 +2858,17 @@
                     // no_update is true when there is no need for coherence transaction
                     bool no_update = ( (r_write_count.read() == 0) or
-                            (owner and (r_write_count.read() ==1) and 
-                             (r_write_pktid.read() != TYPE_SC)));
+                            (owner and (r_write_count.read() == 1) and 
+                             ((r_write_pktid.read() & 0x7) != TYPE_SC)));
 
                     // write data in the cache if no coherence transaction
                     if (no_update)
                     {
+                        // SC command but zero copies 
+                        if ((r_write_pktid.read() & 0x7) == TYPE_SC)
+                        {
+                            m_llsc_table.sc(r_write_address.read(),
+                                            r_write_sc_key.read());
+                        }
+
                         for(size_t word=0 ; word<m_words ; word++)
                         {
@@ -2867,5 +2881,5 @@
                     }
 
-                    if (owner and not no_update and(r_write_pktid.read() != TYPE_SC))
+                    if (owner and not no_update and ((r_write_pktid.read() & 0x7) != TYPE_SC))
                     {
                         r_write_count = r_write_count.read() - 1;
@@ -2936,4 +2950,11 @@
                         if (wok )       // write data in cache
                         {
+                            
+                            if ((r_write_pktid.read() & 0x7) == TYPE_SC)
+                            {
+                                m_llsc_table.sc(r_write_address.read(),
+                                                r_write_sc_key.read());
+                            }
+
                             for(size_t word=0 ; word<m_words ; word++)
                             {
@@ -2999,8 +3020,9 @@
                     size_t min = r_write_word_index.read();
                     size_t max = r_write_word_index.read() + r_write_word_count.read();
-                    for(size_t i=min ; i<max ; i++) r_write_to_cc_send_data[i] = r_write_data[i];
+                    for(size_t i=min ; i<=max ; i++) r_write_to_cc_send_data[i] = r_write_data[i];
 
                     if ((r_write_copy.read() != r_write_srcid.read()) or
-                            (r_write_pktid.read() == TYPE_SC) or r_write_copy_inst.read())
+                       ((r_write_pktid.read() & 0x7) == TYPE_SC)      or
+                         r_write_copy_inst.read())
                     {
                         // put the first srcid in the fifo
@@ -3060,5 +3082,6 @@
                     // put the next srcid in the fifo
                     if ((entry.owner.srcid != r_write_srcid.read()) or 
-                            (r_write_pktid.read() == TYPE_SC) or entry.owner.inst)   
+                       ((r_write_pktid.read() & 0x7) == TYPE_SC)    or
+                         entry.owner.inst)
                     {
                         dec_upt_counter                = false;
@@ -3140,5 +3163,5 @@
                 // a new request in the write FIFO
                 {
-                    if (!r_write_to_tgt_rsp_req.read())
+                    if (not r_write_to_tgt_rsp_req.read())
                     {
                         // post the request to TGT_RSP_FSM
@@ -3150,5 +3173,9 @@
 
                         // try to get a new write request from the FIFO
-                        if (m_cmd_write_addr_fifo.rok())
+                        if (not m_cmd_write_addr_fifo.rok())
+                        {
+                            r_write_fsm = WRITE_IDLE;
+                        }
+                        else
                         {
                             // consume a word in the FIFO & write it in the local buffer
@@ -3158,10 +3185,19 @@
                             r_write_address     = (addr_t) (m_cmd_write_addr_fifo.read());
                             r_write_word_index  = index;
-                            r_write_word_count  = 1;
+                            r_write_word_count  = 0;
                             r_write_data[index] = m_cmd_write_data_fifo.read();
                             r_write_srcid       = m_cmd_write_srcid_fifo.read();
                             r_write_trdid       = m_cmd_write_trdid_fifo.read();
                             r_write_pktid       = m_cmd_write_pktid_fifo.read();
-                            r_write_pending_sc  = false;
+
+                            // if SC command, get the SC key
+                            if ((m_cmd_write_pktid_fifo.read() & 0x7) == TYPE_SC)
+                            {
+                                assert( not m_cmd_write_eop_fifo.read() &&
+                                        "MEMC ERROR in WRITE_RSP state: "
+                                        "invalid packet format for SC command");
+
+                                r_write_sc_key = m_cmd_write_data_fifo.read();
+                            } 
 
                             // initialize the be field for all words
@@ -3169,8 +3205,8 @@
                             {
                                 if (word == index) r_write_be[word] = m_cmd_write_be_fifo.read();
-                                else                 r_write_be[word] = 0x0;
+                                else               r_write_be[word] = 0x0;
                             }
 
-                            if (m_cmd_write_eop_fifo.read() or ((m_cmd_write_pktid_fifo.read() & 0x7)  == TYPE_SC))
+                            if (m_cmd_write_eop_fifo.read())
                             {
                                 r_write_fsm = WRITE_DIR_REQ;
@@ -3180,8 +3216,4 @@
                                 r_write_fsm = WRITE_NEXT;
                             }
-                        }
-                        else
-                        {
-                            r_write_fsm = WRITE_IDLE;
                         }
 
@@ -3221,21 +3253,38 @@
                         bool    wok       = not m_trt.full(wok_index);
 
-                        if (hit_read)      // register the modified data in TRT
+                        // wait an empty entry in TRT
+                        if(not hit_read and (not wok or hit_write))
+                        {
+                            r_write_fsm       = WRITE_WAIT;
+                            m_cpt_trt_full++;
+
+                            break;
+                        }
+
+                        if ((r_write_pktid.read() & 0x7) == TYPE_SC)
+                        {
+                            m_llsc_table.sc(r_write_address.read(),
+                                            r_write_sc_key.read());
+                        }
+
+                        // register the modified data in TRT
+                        if (hit_read)
                         {
                             r_write_trt_index = hit_index;
                             r_write_fsm       = WRITE_MISS_TRT_DATA;
                             m_cpt_write_miss++;
-                        }
-                        else if (wok and !hit_write)      // set a new entry in TRT
+                            break;
+                        }
+
+                        // set a new entry in TRT
+                        if (wok and not hit_write)
                         {
                             r_write_trt_index = wok_index;
                             r_write_fsm       = WRITE_MISS_TRT_SET;
                             m_cpt_write_miss++;
-                        }
-                        else    // wait an empty entry in TRT
-                        {
-                            r_write_fsm       = WRITE_WAIT;
-                            m_cpt_trt_full++;
-                        }
+                            break;
+                        }
+
+                        assert(false && "VCI_MEM_CACHE ERROR: this part must not be reached");
                     }
                     break;
@@ -3477,4 +3526,10 @@
 
                     m_cache_directory.write(set, way, entry);
+
+                    if ((r_write_pktid.read() & 0x7) == TYPE_SC)
+                    {
+                        m_llsc_table.sc(r_write_address.read(),
+                                        r_write_sc_key.read());
+                    }
 
 #if DEBUG_MEMC_WRITE
@@ -6284,5 +6339,5 @@
                 {
                     if (not p_dspin_m2p.read) break;
-                    if (r_cc_send_cpt.read() == (r_write_to_cc_send_count.read() - 1))
+                    if (r_cc_send_cpt.read() == r_write_to_cc_send_count.read())
                     {
                         write_to_cc_send_fifo_get = true;
@@ -8306,5 +8361,5 @@
 
                     p_dspin_m2p.write = true;
-                    p_dspin_m2p.eop   = (r_cc_send_cpt.read() == (r_write_to_cc_send_count.read()-1));
+                    p_dspin_m2p.eop   = (r_cc_send_cpt.read() == r_write_to_cc_send_count.read());
                     p_dspin_m2p.data  = flit;
 
