#include <systemc.h>
#include <iostream>
#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.fail()) {
            cerr << "error opening file : "  << filename << endl;
            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;
    }
};

