Index: /trunk/Makefile
===================================================================
--- /trunk/Makefile	(revision 2)
+++ /trunk/Makefile	(revision 2)
@@ -0,0 +1,30 @@
+SYSTEMC=../lib/systemc
+
+CPP=g++
+CC=gcc
+#OPT=-O3 
+DEBUG=-g
+OTHER=-Wall
+CFLAGS= $(OTHER) $(DEBUG)
+
+MODULE = run
+SRCS = util.cpp \
+	   processing_queue.cpp \
+	   main.cpp \
+	   processor.cpp \
+	   l1cache.cpp \
+	   l2cache.cpp \
+	   monitor.cpp \
+	   cache_store.cpp
+
+CXXSRCS=$(filter %.cpp, $(SRCS))
+CSRCS=$(filter %.c, $(SRCS))
+
+
+OBJSPP=$(CXXSRCS:.cpp=.o)
+OBJS=$(CSRCS:.c=.o)
+
+include ./Makefile.defs
+
+test:
+	./run.x tests/simple_loop/addresses.adr
Index: /trunk/Makefile.defs
===================================================================
--- /trunk/Makefile.defs	(revision 2)
+++ /trunk/Makefile.defs	(revision 2)
@@ -0,0 +1,39 @@
+#SYSTEMC=/users/outil/systemc/systemc-2.1.v1
+#SYSTEMC=/users/cao/guillaumeb/Desktop/systemc-2.2.0
+INCDIR=-I$(SYSTEMC)/include
+LIBDIR=-L$(SYSTEMC)/lib-$(TARGET_ARCH)
+LIBS=-lsystemc -lm $(EXTRA_LIBS)
+EXE=$(MODULE).x
+
+LBITS := $(shell getconf LONG_BIT)
+ifeq ($(LBITS),64)
+TARGET_ARCH=linux64
+else
+TARGET_ARCH=linux
+endif
+
+
+.SUFFIXES: .c .cc .cpp .o .x
+
+$(EXE): $(OBJSPP) $(OBJS) $(SYSTEMC)/lib-$(TARGET_ARCH)/libsystemc.a
+	ctags -R --c++-kinds=+p --fields=+iaS --extra=+q --language-force=C++ .
+	$(CPP) $(CFLAGS) $(INCDIR) $(LIBDIR) $^ -o $@ 
+
+.cpp.o:
+	$(CPP) $(CFLAGS) $(INCDIR) -c $< -o $@
+
+.cc.o:
+	$(CPP) $(CFLAGS) $(INCDIR) -c $< -o $@
+
+.c.o:
+	$(CC) $(CFLAGS) $(INCDIR) -c $< -o $@
+
+clean:
+	rm -f $(OBJS) $(OBJSPP) *~ core
+
+cleanall: clean
+	rm -f Makefile.deps $(EXE)
+
+Makefile.deps:
+	$(CC) $(CFLAGS) $(INCDIR) -M $(SRCS) >> Makefile.deps
+
Index: /trunk/README
===================================================================
--- /trunk/README	(revision 2)
+++ /trunk/README	(revision 2)
@@ -0,0 +1,13 @@
+
+1/ compilation
+    attention, la librairie systemc doit se trouver dans le rÃ©pertoire ../lib
+
+    commandes :
+        make
+
+2/ Lancer un test
+
+    commandes :
+        make test
+
+
Index: /trunk/address.h
===================================================================
--- /trunk/address.h	(revision 2)
+++ /trunk/address.h	(revision 2)
@@ -0,0 +1,62 @@
+#ifndef ADDRESS_H_
+#define ADDRESS_H_
+
+#include <systemc.h>
+#include <iomanip>
+#include <iostream>
+#include "raw_address.h"
+
+class Address {
+    public:
+        unsigned int block_size;
+        unsigned int block;
+        unsigned int displacement;
+
+        // default constructor
+        Address (const unsigned int block = 0, const unsigned long displacement = 0, const unsigned int block_size = 0) {
+            this->block = block;
+            this->displacement = displacement;
+            this->block_size = block_size;
+        }
+
+        Address (const RawAddress req, const int block_size)
+        {
+            this->block = req.address / block_size;
+            this->displacement = req.address % block_size;
+            this->block_size = block_size;
+        }
+
+        inline bool operator == (const Address & rhs) const {
+            return (rhs.block * rhs.block_size + rhs.displacement == block * block_size + displacement );
+        }
+
+        inline Address& operator = (const Address& rhs) {
+            block = rhs.block;
+            block_size = rhs.block_size;
+            displacement = rhs.displacement;
+            return *this;
+        }
+
+        inline friend void sc_trace(sc_trace_file *tf, const Address & v, const std::string & NAME ) {
+            // FIXME
+            //  sc_trace(tf,v.block, NAME + ".info");
+            //  sc_trace(tf,v.displacement, NAME + ".flag");
+        }
+
+        inline friend ostream& operator << ( ostream& os,  Address const & v ) {
+            os << "0x" << hex << std::setfill('0') << std::setw(8) <<  (v.block * v.block_size + v.displacement) ;
+            return os;
+        }
+
+        inline bool operator < (const Address & rhs) const {
+            return (rhs.block * rhs.block_size + rhs.displacement < block * block_size + displacement); 
+        }
+
+        inline const unsigned int as_absolute() {
+            return (block * block_size + displacement);
+        }
+
+};
+#endif
+
+
Index: /trunk/cache_store.cpp
===================================================================
--- /trunk/cache_store.cpp	(revision 2)
+++ /trunk/cache_store.cpp	(revision 2)
@@ -0,0 +1,121 @@
+#include "cache_store.h"
+
+
+// FIXME is_loaded : addresse de block et non addresse absolues
+//    Le cache store ne stocke que des lignes et se moque des adresses
+
+/*
+bool CacheStore::is_loaded( list<int> *lines, int line)
+{
+    list<int>::iterator it;
+
+    //
+    // simple lookup : iterates over all elements and
+    // returns true if found
+    //
+    for(it = lines->begin(); it != lines->end(); ++it)
+    {
+        if(*it == line )
+            return true;
+    }
+
+    return false;
+}
+*/
+
+bool CacheStore::is_loaded(Address address)
+{
+    list<int>::iterator it;
+
+    if (associativity == DIRECT_MAPPING) {
+        // direct mapping :
+        //  the data is in a set determined by its modulo. The set size is 1
+        unsigned int location = address.block;
+        std::list<int> set = cache_lines[location];
+
+        // this should be only one iteration
+        for (it=set.begin(); it!= set.end(); ++it)
+        {
+            if (*it == address.block)
+                return true;
+        }
+        return false;
+
+    } else if (associativity == FULLY_ASSOCIATIVE) {
+        // fully associative : 
+        //    the data can be anywhere in the set. There is only 1 set, and it is
+        //    in index 0
+
+        // FIXME URGENT CA PLANTE ICI
+        std::list<int> set = cache_lines[0];
+
+        for (it=set.begin(); it != set.end(); ++it)
+        {
+            if (*it == address.block)
+                return true;
+        }
+        return false;
+
+    } else {
+        // N-Way associative :
+        //    the data can be anywhere in a N-Set which position is given
+        //    by the modulo
+        unsigned int location = address.block;
+        std::list<int> set = cache_lines[location];
+
+        for (it = set.begin(); it != set.end(); ++it)
+        {
+            if (*it == address.block)
+                return true;
+        }
+        return false;
+    }
+}
+
+/*
+void CacheStore::do_load( list<int> *lines, int line)
+{
+   
+     * LRU placement :
+     * if the list contains more than *N* associativity
+     *  remove the oldest element (back)
+     *  and insert the new element (front)
+     *
+    if ( lines->size() >= associativity)
+        lines->pop_back();
+
+    lines->push_front(line); 
+}*/
+
+int CacheStore::get_line_width()
+{
+    return this->line_width;
+}
+
+// FIXME harmonize between address.absolute % line_width
+//                  and    address.block
+void CacheStore::do_load(Address address)
+{
+   // LRU replacement :
+   // if the list contains more than *N* (assossiativity)
+   //   then remove the oldest element (back)
+   //   and insert the new element (front)
+   if (associativity ==  DIRECT_MAPPING) {
+       unsigned int location = address.as_absolute() % line_width;
+       if (cache_lines[location].size() >= associativity)
+           cache_lines[location].pop_back();
+
+       cache_lines[location].push_front(address.block);
+
+   } else if (associativity == FULLY_ASSOCIATIVE) {
+       if(cache_lines[0].size() >= num_lines)
+           cache_lines[0].pop_back();
+       cache_lines[0].push_front(address.block);
+   } else {
+
+       unsigned int location = address.block;
+       if(cache_lines[location].size() >= associativity)
+           cache_lines[location].pop_back();
+       cache_lines[location].push_front(address.block);
+   }
+}
Index: /trunk/cache_store.h
===================================================================
--- /trunk/cache_store.h	(revision 2)
+++ /trunk/cache_store.h	(revision 2)
@@ -0,0 +1,71 @@
+#ifndef CACHE_STORE_H
+#define CACHE_STORE_H
+#include <list>
+#include "address.h"
+
+using namespace std;
+
+typedef enum associativity {
+    FULLY_ASSOCIATIVE = 0,
+    DIRECT_MAPPING = 1,
+    WAY_2 = 2,
+    WAY_4 = 4,
+    WAY_8 = 8
+} t_assoc;
+
+class CacheStore {
+
+    private:
+        unsigned int cache_size;
+        unsigned int line_width;
+        t_assoc associativity;
+        unsigned int num_lines;
+        unsigned int num_sets;
+
+        // loaded cache lines : stores  
+        list<int> *cache_lines;
+
+    public:
+        CacheStore( int cache_size, 
+                    int line_width, 
+                    t_assoc associativity ) {
+
+            // attributes initialization
+            this->cache_size = cache_size;
+            this->line_width = line_width;
+            this->associativity = associativity;
+
+            this->num_lines = cache_size / line_width;
+            if (associativity != FULLY_ASSOCIATIVE)
+                this->num_sets = num_lines / associativity;
+            else
+                this->num_sets = 1;
+            this->cache_lines = new list<int>[num_sets];
+
+            // cache lines array initialization
+            for (unsigned int i=0; i < num_sets; i++) {
+                cache_lines[i] = list<int>();
+            }
+
+            // Print parameters
+            cout << ">>> parameters:" << endl;
+            cout << "       cache_size = " << cache_size << endl;
+            cout << "       line_width = " << line_width << endl;
+            cout << "       associativity = " << associativity << endl;
+            cout << "       number of lines = " << num_lines << endl << endl;
+        }
+
+        //bool is_loaded(list<int> *lines, int line);
+        bool is_loaded(Address address);
+
+        //void do_load(list<int> *lines, int line);
+        void do_load(Address address);
+
+        int get_line_width();
+
+        ~CacheStore() {
+            delete [] cache_lines;
+        }
+};
+
+#endif
Index: /trunk/instr.h
===================================================================
--- /trunk/instr.h	(revision 2)
+++ /trunk/instr.h	(revision 2)
@@ -0,0 +1,25 @@
+#ifndef INSTR_H_
+#define INSTR_H_
+
+typedef struct instr_t {
+    int type;
+    int data;
+} instr_t, * instr_ptr;
+
+class LoadRequest {
+    private:
+
+        // the address of data to load
+        int address;
+        int 
+
+    public:
+        Instr() {
+
+        }
+
+        inline
+
+}
+
+#endif
Index: /trunk/l1cache.cpp
===================================================================
--- /trunk/l1cache.cpp	(revision 2)
+++ /trunk/l1cache.cpp	(revision 2)
@@ -0,0 +1,74 @@
+#include "l1cache.h"
+
+
+void L1Cache::read()
+{
+    // On donne la priorité aux éléments en attente :
+    //      - si des éléments sont présents dans la file d'attente
+    //          on les envoie
+    //      - TODO on doit pouvoir les packer pour pouvoir les envoyer par deux
+    //      - si aucun élément n'est présent dans la liste, on arrête d'envoyer (in_activate = false)
+    // indépendemment,
+    //      - si on recoit un élement, on regarde s'il est chargé dans le cache:
+    //          - si il est chargé, on le place dans la liste des addresses à envoyer,
+    //              on attend un moment timeout avant de l'envoyer
+    //          - si il n'est pas chargé, on envoit une requete au cache L2,
+    //              on le place dans la liste des addresses à envoyer.
+    //      - XXX le timeout devrait peut etre etre effectué, meme pour les données non présentes dans le L1
+
+    miss_info = false;
+    hit_info = false;
+
+    if (in_activate) {
+
+        // Retrieves the address
+        RawAddress req = in_data;
+        Address element(req, cstore->get_line_width());
+
+        // Si la donnée est chargée dans le cache
+        if (cstore->is_loaded(element)) {
+            
+            out_activate = true;
+
+            // affichage de l'action
+            cout << sc_time_stamp() << " L1Cache : access to loaded data [" << element << "]  -> hit" << endl;
+
+
+            hit_info = true;
+            out_data = in_data;
+        } else {
+
+            // affichage de l'action
+            cout << sc_time_stamp() << " L1Cache : access to loaded data [" << element << "]  -> miss" << endl; 
+
+            miss_info = true;
+            processing_queue->insert(element, latency);
+            processing_queue->print();
+        }
+    }
+
+    Address *head = processing_queue->get_next_ready(); 
+    if (head != NULL)
+    {
+        cout << "has ready elements " << endl;
+        //processing_queue->print();
+
+        cstore->do_load(*head);
+
+        // Envoi de la réponse au processeur
+        RawAddress req(head->as_absolute());
+        out_activate = true;
+        out_data = req;
+    } else if (! in_activate) {
+        out_activate = false;
+    }
+
+    processing_queue->update_time();
+    
+}
+
+
+void L1Cache::write()
+{
+    // cout << sc_time_stamp() << " L1Cache.write()" << endl;
+}
Index: /trunk/l1cache.h
===================================================================
--- /trunk/l1cache.h	(revision 2)
+++ /trunk/l1cache.h	(revision 2)
@@ -0,0 +1,73 @@
+#include <systemc.h>
+#include "util.h"
+#include "queue.h"
+#include "processing_queue.h"
+#include "address.h"
+#include "raw_address.h"
+#include "cache_store.h"
+
+using namespace std;
+
+SC_MODULE(L1Cache)
+{
+    sc_in_clk clock;
+
+    // signal request from processor
+    sc_in <RawAddress> in_data;
+    sc_in <bool>in_activate;
+
+    // signal answers to processor
+    sc_out<RawAddress> out_data;
+    sc_out<bool> out_activate;
+
+    // XXX temporary signal for out information (for monitoring)
+    sc_out<bool> miss_info;
+    sc_out<bool> hit_info;
+   
+    // Queue de sortie : pour limiter le nombre de requetes simultannÃ©es 
+    Queue<Address> *output_queue;
+
+    // CacheStore : contient les lignes actuellement stockÃ©es dans le cache
+    CacheStore *cstore;
+
+    // Processing queue : timeout interne pour l'envoi de donnÃ©es
+    // qui sont chargÃ©es dans ce cache
+    ProcessingQueue *processing_queue;
+
+    // Latence : delai nÃ©cessaire pour temporiser les donnÃ©es chargÃ©es dans ce
+    // cache
+    unsigned int latency;
+
+
+    // methods for handling memory requests (systemc)
+    void read();
+    void write();
+
+
+
+    L1Cache(sc_module_name name, int cache_size, int line_width, t_assoc associativity, unsigned int latency) : sc_module(name)
+    {
+        this->cstore = new CacheStore(cache_size, line_width, associativity);
+        this->latency = latency;
+
+  //      this->input_queue = new Queue(10);
+        this->processing_queue = new ProcessingQueue(10);
+
+        SC_METHOD(read);
+        dont_initialize();
+        sensitive << clock.neg();
+
+        SC_METHOD(write);
+        dont_initialize();
+        sensitive << clock.neg();
+    };
+    
+    SC_HAS_PROCESS(L1Cache);
+
+    ~L1Cache()
+    {
+        //delete input_queue;
+        delete processing_queue;
+        delete cstore;
+    }
+};
Index: /trunk/l2cache.cpp
===================================================================
--- /trunk/l2cache.cpp	(revision 2)
+++ /trunk/l2cache.cpp	(revision 2)
@@ -0,0 +1,75 @@
+#include "l2cache.h"
+
+void L2Cache::read()
+{
+    // On donne la prioritÃ© aux Ã©lÃ©ments en attente :
+    //      - si des Ã©lÃ©ments sont prÃ©sents dans la file d'attente
+    //          on les envoie
+    //      - TODO on doit pouvoir les packer pour pouvoir les envoyer par deux
+    //      - si aucun Ã©lÃ©ment n'est prÃ©sent dans la liste, on arrÃªte d'envoyer (in_activate = false)
+    // indÃ©pendemment,
+    //      - si on recoit un Ã©lement, on regarde s'il est chargÃ© dans le cache:
+    //          - si il est chargÃ©, on le place dans la liste des addresses Ã  envoyer,
+    //              on attend un moment timeout avant de l'envoyer
+    //          - si il n'est pas chargÃ©, on envoit une requete au cache L2,
+    //              on le place dans la liste des addresses Ã  envoyer.
+    //      - XXX le timeout devrait peut etre etre effectuÃ©, meme pour les donnÃ©es non prÃ©sentes dans le L1
+
+    miss_info = false;
+    hit_info = false;
+
+    if (in_activate) {
+
+        // Retrieves the request address
+        RawAddress req = in_data;
+        Address element(req, cstore->get_line_width());
+
+        // Si la donnÃ©e est chargÃ©e dans le cache
+        if (cstore->is_loaded(element)) {
+            
+            out_activate = true;
+
+            // affichage de l'action
+            cout << sc_time_stamp() << " L2Cache : access to loaded data [" <<
+                element << "]  -> hit" << endl;
+
+
+            hit_info = true;
+            out_data = in_data;
+        } else {
+
+            // affichage de l'action
+            cout << sc_time_stamp() << " L2Cache : access to loaded data [" <<
+                element << "]  -> miss" << endl; 
+
+            miss_info = true;
+            processing_queue->insert(element, latency);
+            processing_queue->print();
+        }
+    }
+
+    Address *head = processing_queue->get_next_ready(); 
+    if (head != NULL)
+    {
+        cout << "has ready elements " << endl;
+        //processing_queue->print();
+
+        cstore->do_load(*head);
+
+        // Envoi de la rÃ©ponse au processeur
+        RawAddress req(head->as_absolute());
+        out_activate = true;
+        out_data = req;
+    } else if (! in_activate) {
+        out_activate = false;
+    }
+
+    processing_queue->update_time();
+    
+}
+
+
+void L2Cache::write()
+{
+    // cout << sc_time_stamp() << " L2Cache.write()" << endl;
+}
Index: /trunk/l2cache.h
===================================================================
--- /trunk/l2cache.h	(revision 2)
+++ /trunk/l2cache.h	(revision 2)
@@ -0,0 +1,74 @@
+#ifndef L2CACHE_H_
+#define L2CACHE_H_
+
+#include <systemc.h>
+#include "address.h"
+#include "queue.h"
+#include "processing_queue.h"
+#include "cache_store.h"
+
+SC_MODULE(L2Cache)
+{
+    // clock
+    sc_in_clk clock;
+
+    // signal request from l1
+    sc_in <RawAddress> in_data;
+    sc_in <bool> in_activate;
+
+    sc_out <RawAddress> out_data;
+    sc_out <bool> out_activate;
+
+    // XXX temporary signal for out information (for monitoring)
+    sc_out<bool> miss_info;
+    sc_out<bool> hit_info;
+
+    // Queue de sortie : pour limiter le nombre de requetes simultannÃ©es 
+    Queue<Address> *output_queue;
+
+    // CacheStore : contient les lignes actuellement stockÃ©es dans le cache
+    CacheStore *cstore;
+
+    // Processing queue : timeout interne pour l'envoi de donnÃ©es
+    // qui sont chargÃ©es dans ce cache
+    ProcessingQueue *processing_queue;
+
+    // Latence : dÃ©lai nÃ©cesaire pour temporiser l'envoi de donnÃ©es
+    // chargÃ©es dans ce cache
+    unsigned int latency;
+    
+    // methods for handling memory requests (systemc)
+    void read();
+    void write();
+
+    L2Cache(sc_module_name name, 
+            int cache_size, 
+            int line_width, 
+            t_assoc associativity,
+            unsigned int latency) : sc_module(name)
+    {
+        this->cstore = new CacheStore(cache_size, line_width, associativity);
+        this->latency = latency;
+        this->output_queue = new Queue<Address>(10);
+        this->processing_queue = new ProcessingQueue(10);
+
+        SC_METHOD(read);
+        dont_initialize();
+        sensitive << clock.pos();
+
+        SC_METHOD(write);
+        dont_initialize();
+        sensitive << clock.pos();
+    };
+
+    SC_HAS_PROCESS(L2Cache);
+
+    ~L2Cache()
+    {
+        delete output_queue;
+        delete processing_queue;
+        delete cstore;
+    }
+};
+
+#endif
Index: /trunk/main.cpp
===================================================================
--- /trunk/main.cpp	(revision 2)
+++ /trunk/main.cpp	(revision 2)
@@ -0,0 +1,59 @@
+#include "processor.h"
+#include "l1cache.h"
+#include "address.h"
+#include "raw_address.h"
+#include "monitor.h"
+#include "cache_store.h"
+#define TAILLE_LIGNE 8
+
+int sc_main(int argc, char **argv)
+{
+    if (argc != 2) {
+        cout << "usage : " << argv[0] << " filename" << endl;
+        exit(0);
+    }
+
+    sc_clock clock("Clock", 1,SC_NS); 
+
+    sc_signal<RawAddress> request;
+    sc_signal<RawAddress> answer;
+
+    sc_signal<bool> l1_activate;
+    sc_signal<bool> proc_activate;
+
+    sc_signal<bool> l1miss_info;
+    sc_signal<bool> l1hit_info;
+
+    Processor processor("Processor", argv[1]);
+    L1Cache   l1cache("L1Cache", 256, TAILLE_LIGNE, FULLY_ASSOCIATIVE, 2);
+    Monitor   monitor("Monitor");
+
+    processor.clock(clock);
+    l1cache.clock(clock);
+    monitor.clock(clock);
+
+    l1cache.in_activate(l1_activate);
+    processor.out_activate(l1_activate);
+
+    l1cache.out_activate(proc_activate);
+    processor.in_activate(proc_activate);
+
+    processor.out_data(request);
+    l1cache.in_data(request);
+
+    processor.in_data(answer);
+    l1cache.out_data(answer);
+
+
+
+    l1cache.hit_info(l1hit_info);
+    monitor.l1hit_signal(l1hit_info);
+
+    l1cache.miss_info(l1miss_info);
+    monitor.l1miss_signal(l1miss_info);
+
+
+
+    sc_start(1000, SC_NS);
+    return 0;
+}
Index: /trunk/monitor.cpp
===================================================================
--- /trunk/monitor.cpp	(revision 2)
+++ /trunk/monitor.cpp	(revision 2)
@@ -0,0 +1,26 @@
+#include "monitor.h"
+#include <iostream>
+
+using namespace std;
+
+void Monitor::count_hit()
+{
+    if (l1hit_signal)
+        l1hits++;
+}
+
+void Monitor::count_miss()
+{
+    if (l1miss_signal)
+        l1misses++;
+}
+
+void Monitor::make_my_report()
+{
+    cout << dec << endl <<
+        "Report : " << endl << 
+        "L1 total requests : " << l1hits + l1misses << endl <<
+        "         hits     : " << l1hits << endl << 
+        "         misses   : " << l1misses << endl;
+
+}
Index: /trunk/monitor.h
===================================================================
--- /trunk/monitor.h	(revision 2)
+++ /trunk/monitor.h	(revision 2)
@@ -0,0 +1,32 @@
+#include <systemc.h>
+
+SC_MODULE(Monitor)
+{
+    int l1misses;
+    int l1hits;
+
+    //sc_in<bool> make_report;
+
+    sc_in<bool> l1miss_signal;
+    sc_in<bool> l1hit_signal;
+    sc_in_clk clock;
+
+    void count_hit();
+    void count_miss();
+    void make_my_report();
+
+    SC_CTOR(Monitor)
+    {
+        l1misses = 0;
+        l1hits = 0;
+
+        SC_METHOD(make_my_report);
+        sensitive << clock;
+
+        SC_METHOD(count_hit);
+        sensitive << clock.neg();
+
+        SC_METHOD(count_miss);
+        sensitive << clock.neg();
+    }
+};
Index: /trunk/processing_queue.cpp
===================================================================
--- /trunk/processing_queue.cpp	(revision 2)
+++ /trunk/processing_queue.cpp	(revision 2)
@@ -0,0 +1,127 @@
+#include "processing_queue.h"
+
+void ProcessingQueue::insert(const Address addr, unsigned int latency)
+{
+    ProcessingElement el = 
+    { 
+        addr, 
+        INTERNAL_TIMEOUT,
+        false,
+        latency 
+    };
+    elements.push_back(el);
+}
+
+void ProcessingQueue::insert(const Address addr)
+{
+    ProcessingElement el = 
+    {
+        addr,
+        EXTERNAL_WAIT,
+        false,
+        0
+    };
+    elements.push_back(el);
+}
+
+void ProcessingQueue::update_time()
+{
+    list<ProcessingElement>::iterator it;
+    for (it = elements.begin(); it != elements.end(); it++) {
+        if (it->processing_type == INTERNAL_TIMEOUT) {
+            if (it->latency > 0){
+                it->latency--;
+            } else {
+                // FIXME readd this test
+                // cout << "latency going under 0" << endl;
+            }
+        }
+    }
+}
+
+void ProcessingQueue::mark_ready(Address &element)
+{
+    /*
+    list<ProcessingElement>::iterator it;
+    for (it=elements.begin(); it!= elements.end(); it++) {
+        ProcessingElement el = *it;
+        if (el.address == element) {
+            if (el.processing_type == EXTERNAL_WAIT) {
+                el.is_ready = true;
+            } else {
+                //cout << "marking duplicate or incorrect element as ready" << endl;
+            }
+        }
+    }*/
+}
+
+Address* ProcessingQueue::get_next_ready()
+{
+    
+     //cout << "appel a get_next_ready" << endl;
+    list<ProcessingElement>::iterator it;
+    for (it=elements.begin(); it!= elements.end(); it++) {
+        if (it->processing_type == EXTERNAL_WAIT) {
+            if (it->is_ready == true) {
+                 //cout << "suppression de l'element : " << el;
+                elements.erase(it);
+                return &(it->address);
+            } else {
+                 //cout << "get_next_ready incorrect behavior" << endl;
+                exit (5439405);
+            }
+        } else {
+             //cout << "l'element est en internal timeout" << endl;
+            if (it->latency == 0){
+                 //cout << "suppression de l'element" << *it << endl;
+                elements.erase(it);
+                return &(it->address);
+            }
+        }
+    }
+     //cout << "retour de get_next_ready : null" << endl;
+     
+    return NULL;
+}
+
+/*
+int ProcessingQueue::get_ready_element() {
+    list<ProcessingElement>::iterator it;
+    it = elements.begin();
+    ProcessingElement el = *it;
+    if (el.current_latency != timer) {
+         //cout << "please use has_ready_element before. Aborting" << endl;
+        exit (-123213);
+    } else {
+        elements.pop_front();
+        return el.address;
+    }
+}
+*/
+/*
+bool ProcessingQueue::has_ready_element() 
+{
+    list<ProcessingElement>::iterator it;
+    it = elements.begin();
+    if (elements.size() == 0)
+        return false;
+
+    ProcessingElement el = *it;
+    if (el.current_latency == timer) {
+        return true;
+    } else {
+        return false;
+    }
+}
+*/
+void ProcessingQueue::print()
+{
+    cout << "\t" << "Processing QUEUE START" << endl;
+
+    for(list<ProcessingElement>::iterator it=elements.begin(); it!=elements.end(); it++)
+    {
+        cout << "\t\t" << "element : " << *it << endl;
+    }
+
+    cout << "\t" << "Processing QUEUE STOP" << endl;
+}
Index: /trunk/processing_queue.h
===================================================================
--- /trunk/processing_queue.h	(revision 2)
+++ /trunk/processing_queue.h	(revision 2)
@@ -0,0 +1,78 @@
+#ifndef PROCESSING_QUEUE_H
+#define PROCESSING_QUEUE_H
+
+#include <list>
+#include <iostream>
+#include "util.h"
+#include "address.h"
+
+using namespace std;
+
+enum ProcessingType
+{
+    INTERNAL_TIMEOUT,
+    EXTERNAL_WAIT
+};
+
+struct ProcessingElement {
+    // The data to store
+    Address address;
+
+    // Is the process calculating or waiting for external calculation
+    const ProcessingType processing_type;
+
+    // If the process is done by external calculation, is_ready should
+    // be true when the calculation is finished
+    bool is_ready;
+
+    // If the process is done by internal calculation, this represents
+    // the current timeout.
+    unsigned int latency;
+
+
+    inline friend ostream& operator << ( ostream& os,  ProcessingElement const & v ) {
+        if (v.processing_type == INTERNAL_TIMEOUT) {
+            os << v.address << "(timeout=" << v.latency << ")";
+        } else if (v.processing_type == EXTERNAL_WAIT) {
+            os << v.address << "(extern waiting)";
+        }
+        return os;
+    }
+    
+};
+
+class ProcessingQueue {
+    private:
+        unsigned int max_size;
+        unsigned int current_size;
+        list<ProcessingElement> elements;
+
+    public:
+        ProcessingQueue(int size) {
+            this->max_size = size;
+            this->current_size = 0;
+        }
+
+
+        // Prints the content of the queue
+        void print();
+
+        // marks an external request as ready for being sent
+        void mark_ready(Address &element);
+
+        // insert a request for internal processing, with
+        // specified timeout
+        void insert(const Address addr, unsigned int latency);
+
+        // insert a request for external processing.
+        // will be updated by 
+        void insert(const Address addr);
+
+        Address* get_next_ready();
+
+        // Updates the timeout of all internal requests
+        void update_time();
+};
+
+#endif
+
Index: /trunk/processor.cpp
===================================================================
--- /trunk/processor.cpp	(revision 2)
+++ /trunk/processor.cpp	(revision 2)
@@ -0,0 +1,72 @@
+#include "processor.h"
+
+void Processor::driver()
+{
+    // Si il y a encore des addresses à envoyer
+    if (!file.eof()) {
+
+        // On active le composant recepteur
+        out_activate = true;
+
+        // Et que la file n'est pas pleine, alors on les envoie
+        if (!queue->is_full()) {
+
+            // Vide pour l'instant, c'est la donnée a charger
+            int data;
+            
+            // RawAddresse à charger dans le cache...
+            unsigned int address;
+
+            // Lecture de l'addresse depuis le fichier
+            file >> address;
+            
+            if (file.eof()){
+                out_activate = false;
+                return;
+            }
+
+            cout << "lecture de " << dec << address << " dans le fichier" << endl;
+
+            RawAddress *addr = new RawAddress(address);
+
+            // Si il y a encore des addresses à envoyer
+            cout << sc_time_stamp() << " Processor : request " << *addr << endl;
+
+            // on ajoute la requete a la queue
+            queue->insert(*addr);
+
+            read(*addr, &data);
+        }
+        // Si la file est pleine, il faudra attendre un cycle dans la même
+        // position
+    }
+    // Si il n'y a plus d'addresses à envoyer, on désactive la réception du
+    // coté cache l1.
+    else {
+        // FIXME normalement, c'est superflu
+        // on désactive la reception du coté du cache L1
+        out_activate = false;
+    }
+}
+
+void Processor::completed()
+{
+    if (in_activate) {
+        cout << sc_time_stamp() << " Processor : la donnée " << in_data << " est arrivée" << endl;
+        //queue->print();
+        RawAddress address = in_data;
+        queue->remove(address);
+    }
+}
+
+void Processor::read(RawAddress &address, int *value)
+{
+    // ici, if ready
+    out_data = address;
+}
+
+void Processor::write(RawAddress &address, int value)
+{
+    // ici, if ready
+    out_data = address;
+}
Index: /trunk/processor.h
===================================================================
--- /trunk/processor.h	(revision 2)
+++ /trunk/processor.h	(revision 2)
@@ -0,0 +1,69 @@
+#include <systemc.h>
+#include "util.h"
+#include "queue.h"
+#include "address.h"
+#include "raw_address.h"
+
+/*
+ * Module représentant le processeur.  
+ *
+ * Il est chargé, à chaque tick d'horloge d'envoyer des requêtes au cache L1
+ * qu'il lit dans un fichier spécifié au constructeur.
+ */
+
+SC_MODULE(Processor)
+{
+    // Horloge
+    sc_in_clk clock;
+
+    // File de 10 élements correspondant aux requetes ayant été envoyées et
+    // dont on attend la réponse.  Si elle est pleine, le processeur devra
+    // attendre qu'elle se vide avant de pouvoir envoyer d'autres requetes.
+    Queue<RawAddress> *queue;
+
+    // donnée à envoyer au cache L1
+    sc_out<RawAddress> out_data;
+    sc_out<bool> out_activate;
+
+    // donnée retournée par le cache L1
+    sc_in <RawAddress> in_data;
+    sc_in <bool> in_activate;
+   
+
+    void driver();
+
+    void read(RawAddress &address, int *value);
+    void write(RawAddress &address, int value);
+
+    void completed();
+
+    ifstream file;
+
+    Processor(sc_module_name name, char *filename) : sc_module(name)
+    {
+        // Initialisation
+        this->queue = new Queue<RawAddress>(10);
+
+        file.open(filename, ios::in);
+        if (file.bad()) {
+            cerr << "error opening file";
+            exit (1);   // Erreur a l'ouverture, on quitte... violemment ...
+        }
+
+        // SystemC methods declarations
+        SC_METHOD(driver);
+        dont_initialize();
+        sensitive << clock.pos();
+
+        SC_METHOD(completed);
+        dont_initialize();
+        sensitive << clock.pos();
+    };
+
+    SC_HAS_PROCESS(Processor);
+
+    ~Processor() {
+        delete queue;
+    }
+};
+
Index: /trunk/queue.h
===================================================================
--- /trunk/queue.h	(revision 2)
+++ /trunk/queue.h	(revision 2)
@@ -0,0 +1,96 @@
+#ifndef QUEUE_H_
+#define QUEUE_H_
+
+#include <set>
+#include "raw_address.h"
+#include "util.h"
+#include "queue.h"
+#include <iostream>
+
+/* 
+ * Ceci est une simple file d'attente pour les requêtes de données qui partent
+ * du processeur. 
+ *
+ * Les données sont supprimées de cette file dès qu'elles ont été chargées dans
+ * le processeur. La taille de cette file est fixe. Si un élément est ajouté
+ * alors qu'il dépasse la taille, il ne sera pas inséré.  Néanmoins, un message
+ * devrait s'afficher sur la console.
+ *
+ * Le stockage interne est un arbre binaire rouge-noir qui permet insertion et
+ * suppression en O(log n) de la STL.
+ *
+ * Note: si les élements stockés ne sont plus des entiers, il faudra
+ * probablement ajouter une fonction pour comparer les elements afin que set
+ * puisse les trier.
+ */
+
+template <typename T> 
+class Queue {
+    private:
+        unsigned int max_size;
+        std::set<T> elements;
+
+    public:
+        Queue(int max_size) {
+            this->max_size = max_size;
+        }
+
+        void insert(T &element);
+        void remove(T &element);
+        bool is_full();
+        bool is_empty();
+        void print();
+};
+
+using namespace std;
+
+template < typename T > void Queue<T>::insert(T &element) {
+    if (elements.size() <= max_size) {    
+        elements.insert(element);
+    } else {
+        std::cerr << "insertion ignored" << std::endl;
+    }
+}
+
+template <typename T> bool Queue<T>::is_full() {
+    return (elements.size() == max_size);
+}
+
+template < typename T >bool Queue<T>::is_empty() {
+    return (elements.empty());
+}
+
+template < typename T > void Queue<T>::remove(T &element) {
+    
+    cout << "\t" << "QUEUE suppression de " << element <<  endl;
+
+    if (elements.size() > 1) {
+        typename std::set<T>::iterator it;
+        it = elements.find(element);
+        if (it != elements.end())
+            elements.erase(it);
+        else
+            std::cerr << "removal ignored" << std::endl;
+    }
+
+//    if (elements.size() > 0) {
+//        std::cout << "QUEUE : j'efface l'element : " << element << std::endl;
+//        elements.erase(element);
+//    } else {
+//        std::cerr << "removal ignored" << std::endl;
+//    }
+}
+
+template < typename T > void Queue<T>::print() {
+    typename std::set<T>::iterator it;
+
+    cout << "\t" << "QUEUE begin" << endl;
+    for (it = elements.begin(); it != elements.end(); it++)
+    {
+        cout << "\t\t" << "element : " << *it << endl;
+    }
+
+    cout << "\t" << "QUEUE end" << endl;
+}
+
+#endif
Index: /trunk/raw_address.h
===================================================================
--- /trunk/raw_address.h	(revision 2)
+++ /trunk/raw_address.h	(revision 2)
@@ -0,0 +1,43 @@
+#ifndef CPU_REQ_H_
+#define CPU_REQ_H_
+
+#include <systemc.h>
+#include <iostream>
+#include <iomanip>
+
+class RawAddress {
+
+    public:
+        unsigned int address;
+
+    RawAddress (const unsigned int address = 0) {
+        this->address = address;
+    }
+
+    inline bool operator == (const RawAddress& rhs) const {
+        return (rhs.address == address);
+    }
+
+    inline RawAddress& operator = (const RawAddress& rhs) {
+        address = rhs.address;
+        return *this;
+    }
+    
+
+    inline friend void sc_trace(sc_trace_file *tf, const RawAddress & v, const std::string & NAME ) {
+        // FIXME
+    }
+
+
+    inline friend ostream& operator << ( ostream& os,  RawAddress const & v ) {
+        os << "0x" << hex << std::setfill('0') << std::setw(8) <<  v.address ;
+        return os;
+    }
+    
+    inline bool operator < (const RawAddress& rhs) const {
+        return (rhs.address < address);
+    }
+};
+
+
+#endif
Index: /trunk/util.cpp
===================================================================
--- /trunk/util.cpp	(revision 2)
+++ /trunk/util.cpp	(revision 2)
@@ -0,0 +1,17 @@
+#include <iomanip>
+#include <sstream>
+#include <string>
+
+using namespace std;
+
+std::string str_of_addr(const int address)
+{
+    std::stringstream s;
+    s << "0x" << std::uppercase << std::setw(8) << std::setfill('0') << hex << address;
+
+    //std::string str = s.str();
+    std::string str;
+    s >> str;
+
+    return str;
+}
Index: /trunk/util.h
===================================================================
--- /trunk/util.h	(revision 2)
+++ /trunk/util.h	(revision 2)
@@ -0,0 +1,8 @@
+#ifndef UTIL_H_
+#define UTIL_H_
+
+#include <iostream>
+
+std::string str_of_addr(int address);
+
+#endif
