| [2] | 1 | #include "l1cache.h" |
|---|
| 2 | |
|---|
| [19] | 3 | // TODO il manque un signal pour faire des requetes au L2 |
|---|
| [2] | 4 | |
|---|
| 5 | void L1Cache::read() |
|---|
| 6 | { |
|---|
| 7 | // On donne la priorité aux éléments en attente : |
|---|
| 8 | // - si des éléments sont présents dans la file d'attente |
|---|
| 9 | // on les envoie |
|---|
| 10 | // - TODO on doit pouvoir les packer pour pouvoir les envoyer par deux |
|---|
| 11 | // - si aucun élément n'est présent dans la liste, on arrête d'envoyer (in_activate = false) |
|---|
| 12 | // indépendemment, |
|---|
| 13 | // - si on recoit un élement, on regarde s'il est chargé dans le cache: |
|---|
| 14 | // - si il est chargé, on le place dans la liste des addresses à envoyer, |
|---|
| 15 | // on attend un moment timeout avant de l'envoyer |
|---|
| 16 | // - si il n'est pas chargé, on envoit une requete au cache L2, |
|---|
| 17 | // on le place dans la liste des addresses à envoyer. |
|---|
| 18 | // - XXX le timeout devrait peut etre etre effectué, meme pour les données non présentes dans le L1 |
|---|
| 19 | |
|---|
| 20 | miss_info = false; |
|---|
| 21 | hit_info = false; |
|---|
| [19] | 22 | out_activate = false; |
|---|
| [16] | 23 | |
|---|
| 24 | |
|---|
| 25 | // Est-ce que des élements sont chargés dans ce cache, et prêts à être envoyés ? |
|---|
| 26 | Address *head = processing_queue->get_next_ready(); |
|---|
| 27 | if (head != NULL) // oui |
|---|
| 28 | { |
|---|
| 29 | cout << "has ready elements : " << *head << endl; |
|---|
| 30 | cstore->do_load(*head); |
|---|
| [2] | 31 | |
|---|
| [16] | 32 | // Envoi de la réponse au processeur |
|---|
| 33 | RawAddress req(head->as_absolute()); |
|---|
| 34 | out_activate = true; |
|---|
| 35 | out_data = req; |
|---|
| [2] | 36 | |
|---|
| [16] | 37 | // Sinon, est-ce qu'on est en train de faire une requête ? |
|---|
| 38 | } else if (in_activate) { |
|---|
| 39 | |
|---|
| [2] | 40 | // Retrieves the address |
|---|
| 41 | RawAddress req = in_data; |
|---|
| 42 | Address element(req, cstore->get_line_width()); |
|---|
| 43 | |
|---|
| [16] | 44 | // rappel : processing queue c'est le chargement interne. Si un élement |
|---|
| 45 | // est déjà chargé dans le cache, il va dans la processing queue, |
|---|
| 46 | // sinon, il part en requete dans le L2 |
|---|
| 47 | // |
|---|
| 48 | // |
|---|
| [2] | 49 | // Si la donnée est chargée dans le cache |
|---|
| 50 | if (cstore->is_loaded(element)) { |
|---|
| [19] | 51 | processing_queue->insert(element, latency); |
|---|
| 52 | hit_info = true; |
|---|
| [2] | 53 | |
|---|
| 54 | // affichage de l'action |
|---|
| [19] | 55 | cout << sc_time_stamp() << " L1Cache : access to data [" << element << "] -> hit ... [start loading]" << endl; |
|---|
| [2] | 56 | |
|---|
| 57 | } else { |
|---|
| [19] | 58 | // XXX requete a un module exterieur |
|---|
| [2] | 59 | |
|---|
| 60 | // affichage de l'action |
|---|
| [19] | 61 | cout << sc_time_stamp() << " L1Cache : access to data [" << element << "] -> miss" << endl; |
|---|
| [2] | 62 | |
|---|
| [19] | 63 | out_data = in_data; |
|---|
| [2] | 64 | miss_info = true; |
|---|
| 65 | } |
|---|
| 66 | } |
|---|
| 67 | |
|---|
| [16] | 68 | |
|---|
| 69 | if (!in_activate && processing_queue->is_empty()) { |
|---|
| [2] | 70 | out_activate = false; |
|---|
| 71 | } |
|---|
| 72 | |
|---|
| 73 | processing_queue->update_time(); |
|---|
| 74 | |
|---|
| 75 | } |
|---|
| 76 | |
|---|
| 77 | |
|---|
| 78 | void L1Cache::write() |
|---|
| 79 | { |
|---|
| 80 | // cout << sc_time_stamp() << " L1Cache.write()" << endl; |
|---|
| 81 | } |
|---|