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 291)
+++ trunk/lib/generic_llsc_global_table/include/generic_llsc_global_table.h	(revision 291)
@@ -0,0 +1,496 @@
+/* -*- c++ -*-
+ *
+ * SOCLIB_LGPL_HEADER_BEGIN
+ *
+ * This file is part of SoCLib, GNU LGPLv2.1.
+ *
+ * SoCLib is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; version 2.1 of the License.
+ *
+ * SoCLib is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with SoCLib; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ * SOCLIB_LGPL_HEADER_END
+ *
+ * Alexandre JOANNOU <alexandre.joannou@lip6.fr>
+ *
+ */
+
+#ifndef SOCLIB_GENERIC_LLSC_GLOBAL_TABLE_H
+#define SOCLIB_GENERIC_LLSC_GLOBAL_TABLE_H
+
+#include <systemc>
+#include <arithmetics.h>
+#include <cassert>
+#include <cstring>
+#include <cmath>
+#include <iostream>
+#include <iomanip>
+
+namespace soclib
+{
+
+//////////////////////////
+//TODO switch to this
+/*
+template
+<
+size_t          nb_slots,   // max number of concerned shared resources
+typename        key_t,      // key type => max number of key; TODO wich one ?
+unsigned int    t_network,  // max number of cycle spent in the network when responding to a client (or more)
+unsigned int    t_inter_op, // min number of cycle between 2 reservation operation (or less but > 0)
+typename        addr_t      // ressource identifier type
+>
+*/
+template
+<
+size_t          nb_slots,   // desired number of slots
+unsigned int    nb_procs,   // number of processors in the system
+unsigned int    life_span,  // registratioÃ§n life span (in # of LL operations)
+typename        addr_t      // address type
+>
+class GenericLLSCGlobalTable
+////////////////////////////
+{
+    private :
+
+    const std::string           name              ; // component name
+
+    uint32_t                    r_key  [nb_slots] ; // array of key
+    addr_t                      r_addr [nb_slots] ; // array of addresses
+    bool                        r_val  [nb_slots] ; // array of valid bits
+
+    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
+    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
+
+    ////////////////////////////////////////////////////////////////////////////
+    inline void upNextKey()
+    //  This function generates a new value for the next key
+    {
+        // generating a new key in r_next_key
+        r_next_key++;
+    }
+
+    ////////////////////////////////////////////////////////////////////////////
+    /*
+    inline void updateVictimSlot()
+    //  This function selects the next slot to be evicted
+    //  This is done by updating the value of r_write_ptr
+    {
+        // updates the position of the next slot to be replaced
+
+        static unsigned int count = 0;
+
+
+        // for each slot, check if it actually is the slot to replace
+        // this is done by checking count % 2^(i+1) == (2^i)-1
+        // 2^(i+1) being the period
+        // (2^i)-1 being the first apparition
+        // NB : the -1 in (2^i)-1 is here because of the 0 indexed array
+
+        for (size_t i = 0 ; i < nb_slots; i++)
+            if (count % (int)pow(2,i+1) == pow(2,i)-1)
+                r_write_ptr = i;
+
+        count = (count + 1) % (int) pow(2,nb_slots);    // mustn't go further than 2^nb_slots
+                                                        // or (2^nb_slots)+1 for a 1 indexed array
+                                                        // 2^32 = periodicity of slot #31
+    }
+    */
+    ////////////////////////////////////////////////////////////////////////////
+    inline void updateVictimSlot()
+    //  This function selects the next slot to be evicted
+    //  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;
+
+        new_counter = newCounter(r_block_mask, r_last_counter);
+        xor_counter = new_counter ^ r_last_counter;
+
+        for (size_t i = nb_slots - 1; i >= 0; --i)
+        {
+            if(xor_counter[i])
+            {
+                r_write_ptr = i;
+                break;
+            }
+        }
+
+        r_last_counter = new_counter;
+    }
+
+    ////////////////////////////////////////////////////////////////////////////
+    inline sc_dt::sc_uint<nb_slots> newCounter(const sc_dt::sc_uint<nb_slots>& mask,
+                                               const sc_dt::sc_uint<nb_slots>& counter)
+    // This function generates the new counter //TODO comment more
+    {
+        //
+        return ((((~counter) & (counter << 1)) & mask) | (counter + 1));
+    }
+
+    ////////////////////////////////////////////////////////////////////////////
+    inline void init_block_mask()
+    //TODO
+    //This function selects the block mask to be used
+    //Need to provide another way to do that ?
+    {
+        /*
+        //try to dynamically compute the block mask ...
+        #define L2 soclib::common::uint32_log2
+        unsigned int budget = nb_slots - (L2(nb_procs) + 1); //TODO +1?
+        #undef L2
+        */
+
+        switch(nb_slots)
+        {
+            case 12:
+            r_block_mask = sc_dt::sc_uint<nb_slots>("0x000");
+            break;
+            case 16 :
+            r_block_mask = sc_dt::sc_uint<nb_slots>("0xA800");
+            break;
+            case 20 :
+            r_block_mask = sc_dt::sc_uint<nb_slots>("0xD5500");
+            break;
+            case 24 :
+            r_block_mask = sc_dt::sc_uint<nb_slots>("0xDB5540");
+            break;
+            case 28 :
+            r_block_mask = sc_dt::sc_uint<nb_slots>("0xEEDAAA0");
+            break;
+            case 32 :
+            r_block_mask = sc_dt::sc_uint<nb_slots>("0xF776D550");
+            break;
+            case 36 :
+            r_block_mask = sc_dt::sc_uint<nb_slots>("0xFBDDDB550");
+            break;
+            case 40 :
+            r_block_mask = sc_dt::sc_uint<nb_slots>("0xFDF7BB6D50");
+            break;
+            case 44 :
+            r_block_mask = sc_dt::sc_uint<nb_slots>("0xFEFBDEEDAA8");
+            break;
+            case 48 :
+            r_block_mask = sc_dt::sc_uint<nb_slots>("0xFF7EFBDDDAA8");
+            break;
+            case 52 :
+            r_block_mask = sc_dt::sc_uint<nb_slots>("0xFFBFBF7BBB6A8");
+            break;
+            case 56 :
+            r_block_mask = sc_dt::sc_uint<nb_slots>("0xFFDFEFDF7BB6A8");
+            break;
+            case 60 :
+            r_block_mask = sc_dt::sc_uint<nb_slots>("0xFFF7FDFDF7BB6A8");
+            break;
+            case 64 :
+            r_block_mask = sc_dt::sc_uint<nb_slots>("0xFFFBFF7FBF7BB6A8");
+            break;
+            default:
+            assert(false && "nb_slots must be either 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60 or 64");
+        }
+    }
+
+    ////////////////////////////////////////////////////////////////////////////
+    inline int nextEmptySlot()
+    //  This function returns :
+    //  - the position of the first next empty slot in the table
+    //    (starting from the last empty slot used)
+    //    and updates the r_last_empty_slot register
+    //  - -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
+        return -1;
+    }
+
+    ////////////////////////////////////////////////////////////////////////////
+    inline int hitAddr(const addr_t ad)
+    //  HIT on the address only
+    //  This function takes an addr_t ad
+    //  It returns :
+    //  - the position of the first HIT in the table
+    //  - -1 in case of MISS
+    //  NB : HIT = (slot addr == ad) AND (slot is valid)
+    {
+        // checking all slots
+        for (size_t i = 0; i < nb_slots; i++)
+        {
+            // if HIT, returning its position
+            if(ad == r_addr[i] && r_val[i]) return i;
+        }
+
+        // MISS
+        return -1;
+    }
+
+    ////////////////////////////////////////////////////////////////////////////
+    inline int hitAddrKey(const addr_t ad, const uint32_t key)
+    //  HIT on the address AND the on the signature
+    //  This function takes an addr_t ad and a uint32_t key
+    //  It returns :
+    //  - the position of the first HIT in the table
+    //  - -1 in case of MISS
+    //  NB : HIT = (slot addr == ad) AND (slot key == key)
+    //                               AND (slot is valid)
+    {
+        // checking all slots
+        for (size_t i = 0; i < nb_slots; i++)
+        {
+            // if HIT, returning its position
+            if(ad == r_addr[i] && key == r_key[i] && r_val[i]) return i;
+        }
+
+        // MISS
+        return -1;
+    }
+
+    public:
+
+    ////////////////////////////////////////////////////////////////////////////
+    GenericLLSCGlobalTable( const std::string   &n = "llsc_global_table" )
+    :   name(n)
+    {
+        #define L2 soclib::common::uint32_log2
+        assert(nb_procs > 1); //nb_procs must be more than 1
+        //TODO >= or > ?
+        assert(nb_slots >= L2(nb_procs)); // nb_slot cannot be less then log2(nb_procs)
+        #undef L2
+        init();
+        init_block_mask();
+    }
+
+    ////////////////////////////////////////////////////////////////////////////
+    ~GenericLLSCGlobalTable()
+    {
+    }
+
+    ////////////////////////////////////////////////////////////////////////////
+    inline void init()
+    //  This function initializes the table (all slots empty)
+    {
+        // making all slots available by reseting all valid bits
+        std::memset(r_val, 0, sizeof(*r_val)*nb_slots);
+
+        // init registers
+        r_next_key          = 0;
+        r_last_counter      = 0; //TODO static in updateVictimSlot() ?
+        r_write_ptr         = 0;
+        r_last_empty        = 0;
+
+        // init stat counters
+        m_cpt_evic          = 0;
+        m_cpt_ll            = 0;
+        m_cpt_ll_update     = 0;
+        m_cpt_sc            = 0;
+        m_cpt_sc_success    = 0;
+        m_cpt_sw            = 0;
+    }
+
+    ////////////////////////////////////////////////////////////////////////////
+    inline uint32_t ll(const addr_t ad)
+    //  This method registers an LL in the table and returns the key associated
+    //  with the registration
+    {
+        // increment the ll access counter (for stats)
+        m_cpt_ll++;
+
+        // hit addr ?
+        // YES
+        //      enough time left ?
+        //      YES
+        //          use this registration, return key
+        //      NO
+        //          update this registration with a new key, return new key
+        // NO
+        //      table has an empty slot ?
+        //      YES
+        //              select empty slot
+        //      NO
+        //              select victim slot (r_write_ptr)
+        //              update next victim
+        //      open registration on selected slot
+        //      update next key
+        //      return the registration key
+
+        //  Is the address found in the table ?
+        int pos = hitAddr(ad);
+
+        //  Yes, then return the associated key
+        if (pos >= 0)
+        {
+            if(r_key[pos] - r_next_key > life_span)
+                return r_key[pos];
+            r_key[pos] = r_next_key;
+            upNextKey();
+            m_cpt_ll_update++;
+            return r_key[pos];
+        }
+
+        //  No, then try to find an empty slot
+        pos = nextEmptySlot();
+
+        //  If there is no empty slot,
+        //  evict an existing registration
+        if (pos == -1)
+        {
+            //  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++;
+        }
+
+        // get the key for the new registration
+        uint32_t key    = r_next_key;
+        //  update the registration slot
+        r_key[pos]      = key   ;
+        r_addr[pos]     = ad    ;
+        r_val[pos]      = true  ;
+        //  compute the next key
+        upNextKey();
+
+        // return the key of the new registration
+        return key;
+
+    }
+
+    ////////////////////////////////////////////////////////////////////////////
+    inline bool sc(const addr_t ad, const uint32_t key)
+    //  This method checks if there is a valid registration for the SC (ad &&
+    //  key) and, in case of hit,invalidates the registration and returns true
+    //  (returns false otherwise)
+    //
+    //  The return value can be used to tell if the SC is atomic
+    {
+        // increment the sc access counter (for stats)
+        m_cpt_sc++;
+        // hit addr && hit key ?
+        // NO
+        //      return miss
+        // YES
+        //      inval registration and return hit
+
+        //  Is there a valid registration in the table ?
+        int pos = hitAddrKey(ad, key);
+        if(pos >= 0)
+        {
+            // increment the sc success counter (for stats)
+            m_cpt_sc_success++;
+            // invalidate the registration
+            r_val[pos] = false;
+            // return the success of the sc operation
+            return true;
+        }
+        else
+        {
+            // return the failure of the sc operation
+            return false;
+        }
+    }
+
+    ////////////////////////////////////////////////////////////////////////////
+    inline void sw(const addr_t ad)
+    //  This method checks if there is a valid registration for the given
+    //  address and, in case of hit, invalidates the registration
+    {
+        // increment the sw access counter (for stats)
+        m_cpt_sw++;
+        // hit addr ?
+        // YES
+        //      inval registration
+        // NO
+        //      nothing
+
+        //  Is there a registration for the given address ?
+        int pos = hitAddr(ad);
+        //  If there is one, invalidate it
+        if(pos >= 0) r_val[pos] = false;
+
+    }
+
+    ////////////////////////////////////////////////////////////////////////////
+    /*
+    void fileTrace(FILE* file)
+    {
+    }
+    */
+
+    ////////////////////////////////////////////////////////////////////////////
+    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]    << " | "
+                << 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 ;
+    }
+
+    ////////////////////////////////////////////////////////////////////////////
+    inline void print_stats(std::ostream& out = std::cout)
+    {
+        out << "# of ll accesses : " << m_cpt_ll            << std::endl
+            << "# of ll updates  : " << m_cpt_ll_update     << std::endl
+            << "# of sc accesses : " << m_cpt_sc            << std::endl
+            << "# of sc success  : " << m_cpt_sc_success    << std::endl
+            << "# of sw accesses : " << m_cpt_sw            << std::endl
+            << "# of evictions   : " << m_cpt_evic          << std::endl ;
+    }
+
+};
+
+} // end namespace soclib
+
+#endif
+
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
Index: trunk/lib/generic_llsc_global_table/metadata/generic_llsc_global_table.sd
===================================================================
--- trunk/lib/generic_llsc_global_table/metadata/generic_llsc_global_table.sd	(revision 291)
+++ trunk/lib/generic_llsc_global_table/metadata/generic_llsc_global_table.sd	(revision 291)
@@ -0,0 +1,13 @@
+# -*- python -*-
+
+Module(
+    'caba:generic_llsc_global_table',
+    classname       = 'soclib::GenericLLSCGlobalTable',
+    header_files    = ['../include/generic_llsc_global_table.h'],
+    tmpl_parameters = 
+        [
+            parameter.Int('nb_slots', min = 2, max = 64, default = 32),
+            parameter.Int('nb_procs', min = 2, max = 4096, default = 4095), # default should be 4096, but soclib-cc problem
+            parameter.Type('addr_t', default = 'sc_dt::sc_uint<40>')
+        ]
+)
Index: trunk/lib/generic_llsc_local_table/include/generic_llsc_local_table.h
===================================================================
--- trunk/lib/generic_llsc_local_table/include/generic_llsc_local_table.h	(revision 291)
+++ trunk/lib/generic_llsc_local_table/include/generic_llsc_local_table.h	(revision 291)
@@ -0,0 +1,504 @@
+/* -*- c++ -*-
+ *
+ * SOCLIB_LGPL_HEADER_BEGIN
+ *
+ * This file is part of SoCLib, GNU LGPLv2.1.
+ *
+ * SoCLib is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; version 2.1 of the License.
+ *
+ * SoCLib is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with SoCLib; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ * SOCLIB_LGPL_HEADER_END
+ *
+ * Alexandre JOANNOU <alexandre.joannou@lip6.fr>
+ *
+ */
+
+#ifndef SOCLIB_GENERIC_LLSC_LOCAL_TABLE_H
+#define SOCLIB_GENERIC_LLSC_LOCAL_TABLE_H
+
+#include <systemc>
+#include <cassert>
+#include <cstring>
+#include <iostream>
+#include <iomanip>
+
+namespace soclib {
+
+//////////////////////////
+//TODO switch to this
+/*
+template
+<
+size_t          nb_slots,   // max number of authorized atomic operation per agent
+typename        key_t,      // key type => max number of key; TODO wich one ?
+unsigned int    t_network,  // max number of cycle spent in the network when responding to a client (or more)
+unsigned int    t_inter_op, // min number of cycle between 2 reservation operation (or less but > 0)
+typename        addr_t      // ressource identifier type
+>
+*/
+template
+<
+uint32_t    life_span               ,   // desired life-span for a reservation
+size_t      nb_slots    = 1         ,   // desired number of reservation
+typename    addr_t      = uint32_t  ,   // ressource identifier type
+typename    index_t     = size_t    ,   // transaction index/identifier type (trdid size)
+typename    key_t       = uint32_t      // key identifier type
+>
+class GenericLLSCLocalTable
+///////////////////////////
+{
+    public:
+
+    // command type
+    enum cmd_t
+    {
+        LL_CMD  = 0x8,  // create a reservation in the table (to be called when an ll cmd is emited)
+        LL_RSP  = 0x4,  // updates a reservation in the table (to be called when an ll rsp is received)
+        SC_CMD  = 0x2,  // invalidate a reservation (if necessary) and reset the wait register
+        SW_CMD  = 0x1,  // invalidate a reservation (if necessary)
+        NOP     = 0x0   // no operation (internal updates only : aging counters)
+    };
+
+    struct in_t
+    {
+        addr_t  address ;   // the address  argument of the command
+        index_t index   ;   // the index    argument of the command
+        key_t   key     ;   // the key      argument of the command
+        cmd_t   cmd     ;   // the command for the table to execute
+    };
+
+    struct out_t
+    {
+        bool    done    ;   // true if operation was actually performed
+        bool    hit     ;   // true if there was a hit on the address
+        key_t   key     ;   // the matching key for an SC_CMD
+        index_t index   ;   // the index of the reservation for a LL_CMD
+    };
+
+    private :
+
+    const std::string           name                ;   // component name
+
+    addr_t                      r_addr  [nb_slots]  ;   // array of addresses
+    key_t                       r_key   [nb_slots]  ;   // array of keys
+    uint32_t                    r_cnt   [nb_slots]  ;   // array of aging counters
+    bool                        r_val   [nb_slots]  ;   // array of valid bits
+
+    uint32_t                    r_wait              ;   // number of cycles to wait (when trying to perform a reservation)
+    uint32_t                    r_wait_cnt          ;   // counter counting down from r_wait to 0
+    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_ll_cmd        ;   // number of ll_cmd accesses to the table
+    uint32_t                    m_cpt_ll_cmd_done   ;   // number of ll_cmd accesses to the table (effectivelly done)
+    uint32_t                    m_cpt_ll_rsp        ;   // number of ll_rsp accesses to the table
+    uint32_t                    m_cpt_sc_cmd        ;   // number of sc_cmd accesses to the table
+    uint32_t                    m_cpt_sw_cmd        ;   // number of sw_cmd accesses to the table
+    uint32_t                    m_cpt_nop           ;   // number of nop    accesses to the table
+    uint32_t                    m_cpt_evic          ;   // number of eviction in the table
+    uint32_t                    m_cpt_death         ;   // number of death of reservations due to aging
+
+    ////////////////////////////////////////////////////////////////////////////
+    inline int hitAddr(const addr_t & address)
+    //  HIT on the address only
+    //  This function takes an addr_t address
+    //  It returns :
+    //  - the position of the first HIT in the table
+    //  - -1 in case of MISS
+    //  NB : HIT = (slot addr == ad) AND (slot is valid)
+    {
+        // checking all slots
+        for (size_t i = 0; i < nb_slots; i++)
+        {
+            // if HIT, returning its position
+            if(address == r_addr[i] && r_val[i]) return i;
+        }
+
+        // MISS
+        return -1;
+    }
+
+    ////////////////////////////////////////////////////////////////////////////
+    inline int nextEmptySlot()
+    //  This function returns :
+    //  - the position of the first next empty slot in the table
+    //    (starting from the last empty slot used)
+    //    and updates the r_last_empty_slot register
+    //  - -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
+        return -1;
+    }
+
+    ////////////////////////////////////////////////////////////////////////////
+    inline void updateVictimSlot()
+    //  This function selects the next slot to be evicted
+    //  This is done by updating the value of r_write_ptr
+    {
+        r_write_ptr = 0;
+    }
+
+    public:
+
+    ////////////////////////////////////////////////////////////////////////////
+    GenericLLSCLocalTable(  const std::string    &n = "llsc_local_table" )
+    :   name(n)
+    {
+        init();
+    }
+
+    ////////////////////////////////////////////////////////////////////////////
+    ~GenericLLSCLocalTable()
+    {
+    }
+
+    ////////////////////////////////////////////////////////////////////////////
+    inline void init()
+    //  This function initializes the table (all slots empty)
+    {
+        // making all slots available by reseting all valid bits
+        std::memset(r_val, 0, sizeof(*r_val)*nb_slots);
+
+        // init registers
+        r_wait              = 0;
+        r_wait_cnt          = 0;
+        r_write_ptr         = 0;
+        r_last_empty        = 0;
+
+        // init stat counters
+        m_cpt_ll_cmd        = 0;
+        m_cpt_ll_cmd_done   = 0;
+        m_cpt_ll_rsp        = 0;
+        m_cpt_sc_cmd        = 0;
+        m_cpt_sw_cmd        = 0;
+        m_cpt_nop           = 0;
+        m_cpt_evic          = 0;
+        m_cpt_death         = 0;
+    }
+
+    ////////////////////////////////////////////////////////////////////////////
+    inline void exec(const in_t & in, out_t & out)
+    // This function has to be called every cycle !
+    // It implements the behaviour of the generic_llsc_local_table.
+    // 5 commands can be performed :
+    // - LL_CMD
+    // - LL_RSP
+    // - SC_CMD
+    // - SW_CMD
+    // - NOP
+    // Each one of them are described further below
+    {
+        // First check the command
+        switch(in.cmd)
+        {
+            case LL_CMD :
+            // INPUTS :
+            // - address
+            //
+            // Check if r_wait_cnt has reached 0
+            // - YES
+            //      - the wait counter is re initialized with the content of the
+            //        r_wait register
+            //      - the r_wait register is doubled (<< 1) (delay mechanism)
+            //      - check if there is an empty slot
+            //          if YES, select the empty slot
+            //          if NO, select victim slot and update next victim
+            //      - the address of the selected slot is initialized with the given
+            //        address
+            //      - the aging counter of the selected slot is initialized with
+            //        the life-span of a reservation
+            //      - the valid bit of the selected slot is set to true
+            //
+            //          - out.hit   <= don't care
+            //          - out.done  <= true
+            //          - out.key   <= don't care
+            //          - out.index <= i the index of the selected slot
+            //
+            // - NO
+            //      - decrement r_wait_cnt
+            //
+            //          - out.hit   <= don't care
+            //          - out.done  <= false
+            //          - out.key   <= don't care
+            //          - out.index <= don't care
+            {
+                // increment the ll_cmd access counter (for stats)
+                m_cpt_ll_cmd++;
+
+                if(r_wait_cnt == 0)
+                {
+                    // increment the ll_cmd access counter (effectivelly done) (for stats)
+                    m_cpt_ll_cmd_done++;
+
+                    // increase the lenght of the next waiting session
+                    //r_wait      = (r_wait << 1) + 1 ;
+                    // re initialize the wait counter //TODO check this...
+                    //r_wait_cnt  = r_wait;
+
+                    // select a slot for the reservation
+                    // first check for an empty slot ...
+                    int pos = nextEmptySlot();
+                    // If there is no empty slot,
+                    // evict an existing registration
+                    if (pos == -1)
+                    {
+                        // 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++;
+                    }
+
+                    // inscription in the slot
+                    r_addr  [pos]   =   in.address  ;
+                    r_cnt   [pos]   =   life_span   ;
+                    r_val   [pos]   =   true        ;
+
+                    // construct out argument
+                    //out.hit   = don't care;
+                    out.done    = 1;
+                    //out.key   = don't care;
+                    out.index   = pos;
+                }
+                else
+                {
+                    // decrement the wait counter
+                    r_wait_cnt--;
+
+                    // construct out argument
+                    //out.hit   = don't care;
+                    out.done    = 0;
+                    //out.key   = don't care;
+                    //out.index = don't care;
+                }
+            }
+            break;
+            case LL_RSP :
+            // INPUTS :
+            // - index
+            // - key
+            //
+            //  - the key of the reservation is updated with the given key
+            //
+            //      - out.hit   <= don't care
+            //      - out.done  <= true
+            //      - out.key   <= don't care
+            //      - out.index <= don't care
+            {
+                // increment the ll_rsp access counter (for stats)
+                m_cpt_ll_rsp++;
+
+                // insert new key in reservation
+                r_key[in.index]  = in.key;
+
+                // construct out argument
+                out.hit     = 1;
+                out.done    = 1;
+                //out.key   = don't care;
+                //out.index = don't care;
+            }
+            break;
+            case SC_CMD :
+            // INPUTS :
+            // - address
+            //
+            // Check if there is a hit for the address
+            // - HIT
+            //      - invalidate reservation
+            //      - reset r_wait to 0
+            //
+            //          - out.hit   <= true
+            //          - out.done  <= true
+            //          - out.key   <= r_key[hit_index]
+            //          - out.index <= don't care
+            //
+            // - NO HIT
+            //
+            //      - out.hit   <= false
+            //      - out.done  <= true
+            //      - out.key   <= don't care
+            //      - out.index <= don't care
+            {
+                // increment the sc_cmd access counter (for stats)
+                m_cpt_sc_cmd++;
+
+                // Is there a valid reservation in the table ?
+                int pos = hitAddr(in.address);
+                if(pos >= 0)
+                {
+                    // invalidate reservation
+                    r_val[pos]  = false     ;
+                    // reset r_wait to 0
+                    r_wait      = 0         ;
+                    // construct out argument
+                    out.hit     = 1         ;
+                    out.done    = 1         ;
+                    out.key     = r_key[pos];
+                }
+                else
+                {
+                    // construct out argument
+                    out.hit     = 0;
+                    out.done    = 1;
+                    //out.key   = don't care;
+                    //out.index = don't care;
+                }
+            }
+            break;
+            case SW_CMD :
+            // INPUTS :
+            // - address
+            //
+            // Check if there is a hit for the address
+            // - HIT
+            //      - invalidate reservation
+            //
+            //          - out.hit   <= true
+            //          - out.done  <= true
+            //          - out.key   <= don't care
+            //          - out.index <= don't care
+            //
+            // - NO HIT
+            //
+            //      - out.hit   <= false
+            //      - out.done  <= true
+            //      - out.key   <= don't care
+            //      - out.index <= don't care
+            {
+                // increment the sw_cmd access counter (for stats)
+                m_cpt_sw_cmd++;
+
+                // Is there a valid reservation in the table ?
+                int pos = hitAddr(in.address);
+                if(pos >= 0)
+                {
+                    // invalidate reservation
+                    r_val[pos]  = false     ;
+                    // construct out argument
+                    out.hit     = 1         ;
+                    out.done    = 1         ;
+                    //out.key   = don't care ;
+                    //out.index = don't care;
+                }
+                else
+                {
+                    // construct out argument
+                    out.hit     = 0;
+                    out.done    = 1;
+                    //out.key   = don't care;
+                    //out.index = don't care;
+                }
+            }
+            break;
+            case NOP :
+            // NOTHING except for the usual aging counter updates
+            //
+            //      - out.hit   <= don't care
+            //      - out.done  <= 1
+            //      - out.key   <= don't care
+            //      - out.index <= don't care
+            {
+                // increment the nop access counter (for stats)
+                m_cpt_nop++;
+                // construct out argument
+                //out.hit   = don't care;
+                out.done    = 1;
+                //out.key   = don't care;
+                //out.index = don't care;
+            }
+            break;
+        }
+        // aging counters ...
+        // for each slot
+        for (size_t i = 0; i < nb_slots; i++)
+        {
+            // decrement the counter
+            r_cnt[i]--;
+            // check if the counter has reached 0 (for an actual reservation,
+            // i.e. a valid reservation)
+            if(r_cnt[i] == 0 && r_val[i])
+            {
+                // increment the death counter (for stats)
+                m_cpt_death++;
+                // invalidate the reservation
+                r_val[i] = false;
+            }
+        }
+    }
+
+    ////////////////////////////////////////////////////////////////////////////
+    inline void print_trace(std::ostream& out = std::cout)
+    {
+        out <<  " _________________________________________________" << std::endl
+            <<  "| " << std::setw(47) << "generic_llsc_local_table" << " |" << std::endl
+            <<  "| " << std::setw(47) << name << " |" << std::endl
+            <<  " =================================================" << std::endl
+            <<  "| "
+            <<  std::setw(11) << "addr"   << " | "
+            <<  std::setw(11) << "key"    << " | "
+            <<  std::setw(11) << "cnt"    << " | "
+            <<  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]    << " | "
+                << std::noshowbase
+                << std::setw(11) << std::setfill('0')   << std::dec       << r_key[i]     << " | "
+                << std::setw(11) << std::setfill('0')   << std::dec       << r_cnt[i]     << " | "
+                << std::setw(5)  << std::setfill(' ')   << std::boolalpha << r_val[i]     << " |" << std::endl ;
+        }
+        out <<  " -------------------------------------------------" << std::endl
+            << std::noshowbase << std::dec << std::endl ;
+    }
+
+    ////////////////////////////////////////////////////////////////////////////
+    inline void print_stats(std::ostream& out = std::cout)
+    {
+        out << "# of ll_cmd accesses                     : " << m_cpt_ll_cmd        << std::endl
+            << "# of ll_cmd accesses (effectivelly done) : " << m_cpt_ll_cmd_done   << std::endl
+            << "# of ll_rsp accesses                     : " << m_cpt_ll_rsp        << std::endl
+            << "# of sc_cmd accesses                     : " << m_cpt_sc_cmd        << std::endl
+            << "# of sw_cmd accesses                     : " << m_cpt_sw_cmd        << std::endl
+            << "# of nop    accesses                     : " << m_cpt_nop           << std::endl
+            << "# of eviction                            : " << m_cpt_evic          << std::endl
+            << "# of death by aging                      : " << m_cpt_death         << std::endl ;
+    }
+
+};
+
+} // namespace soclib
+
+#endif
+
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
Index: trunk/lib/generic_llsc_local_table/metadata/generic_llsc_local_table.sd
===================================================================
--- trunk/lib/generic_llsc_local_table/metadata/generic_llsc_local_table.sd	(revision 291)
+++ trunk/lib/generic_llsc_local_table/metadata/generic_llsc_local_table.sd	(revision 291)
@@ -0,0 +1,12 @@
+# -*- python -*-
+
+Module(
+    'caba:generic_llsc_local_table',
+    classname       = 'soclib::GenericLLSCLocalTable',
+    header_files    = ['../include/generic_llsc_local_table.h'],
+    tmpl_parameters = 
+        [
+            parameter.Int('nb_slots', min = 1, max = 10, default = 1),
+            parameter.Type('addr_t', default = 'sc_dt::sc_uint<40>')
+        ]
+)
