#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;
    }
};
