### Try to pop a ready request Source: https://openhw-group-cv-hpdcache.readthedocs-hosted.com/_sources/architecture.rst.txt Attempts to select a ready request from the RTAB using a round-robin policy and manages linked list traversal. ```c req_t rtab_pop_try() { // These are global states (preserved between function calls) static int pop_state = HEAD; static int last = 0; static int next = 0; int index; // Brief description of the following code: // The rtab_pop_try function tries to retire all the requests of a given // linked list. Then it passes to another one. switch (pop_state) { case HEAD: // Find a list whose head request is ready // (using a round-robin policy) index = rtab_find_ready(last); // If there is no ready entry, or there is an ongoing rollback, // return an invalid index if ((index == -1) || rtab_pop_rollback) return -1; // Update the pointer to the last linked list served last = index; // If the list have more than one request, the next time this function // is called, serve the next request of the list if (!rtab[index].ll_tail) { next = rtab[index].ll_next; pop_state = NEXT; } // Temporarily unset the head bit. This is to prevent the // request to be rescheduled. rtab[index].ll_head = 0; break; case NEXT: index = next; // If there is an ongoing rollback, abandon the current pop if (rtab_pop_rollback) { pop_state = HEAD; return -1; } // If the list have more than one request, the next time this function // is called, serve the next request of the list if (!rtab[next].ll_tail) { next = rtab[index].ll_next; pop_state = NEXT; } // It it is the last element of the list, return to the HEAD state else { pop_state = HEAD; } // Temporarily unset the head bit. This is to prevent the // request to be rescheduled. rtab[index].ll_head = 0; } // Pop the selected request return rtab[index].req; } ``` -------------------------------- ### Find ready request Source: https://openhw-group-cv-hpdcache.readthedocs-hosted.com/_sources/architecture.rst.txt Searches for a linked list whose head request is ready for replay using a round-robin policy. ```c int rtab_find_ready(int last) { // choose a ready entry using a round-robin policy int i = (last + 1) % RTAB_NENTRIES; for (;;) { // ready entry found if (rtab[i].valid && rtab[i].ll_head && (rtab[i].deps == 0)) return i; // there is no ready entry if (i == last) return -1; i = (i + 1) % RTAB_NENTRIES; } } ``` -------------------------------- ### Select victim way with select_victim_way function Source: https://openhw-group-cv-hpdcache.readthedocs-hosted.com/architecture.html Implements the victim selection algorithm for cache misses. It returns the first way with valid bit unset, then the first way with LRU bit unset and not being fetched, then a clean way, then a dirty way, and finally -1 if all ways are pre-selected, causing the request to be placed in the replay table. ```c int select_victim_way(int set) { // Return the first way (of the target set) whose valid bit is unset for (int w = 0; w < HPDCACHE_WAYS; w++) { if (!valid[set][w]) { return w; } } // If all ways are valid, return the first way (of the target set) whose // PLRU bit is unset and which is not pre-selected as victim for (int w = 0; w < HPDCACHE_WAYS; w++) { if (!fetch[set][w] && !lru[set][w]) { return w; } } // If the PLRU designated way cannot be selected (already pre-selected // as victim), return the first clean way (no locally modified in case // of write-back policy) for (int w = 0; w < HPDCACHE_WAYS; w++) { if (!fetch[set][w] && !dirty[set][w]) { return w; } } // If there is no clean way selectable, return the first dirty way for (int w = 0; w < HPDCACHE_WAYS; w++) { if (!fetch[set][w]) { return w; } } // If there is no selectable way (all ways are being already pre-selected // and are waiting for a refill) returns -1. In this case the cache // controller puts the miss request on hold in the replay table. return -1; } ``` -------------------------------- ### rtab_pop_try: Select ready request from RTAB Source: https://openhw-group-cv-hpdcache.readthedocs-hosted.com/architecture.html Called by the cache controller to select a ready request (dependencies resolved) from the RTAB. Uses a round-robin policy to find a ready linked list head, handles rollback by returning -1, and updates the head bit to prevent rescheduling. ```c req_t rtab_pop_try() { // These are global states (preserved between function calls) static int pop_state = HEAD; static int last = 0; static int next = 0; int index; // Brief description of the following code: // The rtab_pop_try function tries to retire all the requests of a given // linked list. Then it passes to another one. switch (pop_state) { case HEAD: // Find a list whose head request is ready // (using a round-robin policy) index = rtab_find_ready(last); // If there is no ready entry, or there is an ongoing rollback, // return an invalid index if ((index == -1) || rtab_pop_rollback) return -1; // Update the pointer to the last linked list served last = index; // If the list have more than one request, the next time this function // is called, serve the next request of the list if (!rtab[index].ll_tail) { next = rtab[index].ll_next; pop_state = NEXT; } // Temporarily unset the head bit. This is to prevent the // request to be rescheduled. rtab[index].ll_head = 0; break; case NEXT: index = next; // If there is an ongoing rollback, abandon the current pop if (rtab_pop_rollback) { pop_state = HEAD; return -1; } // If the list have more than one request, the next time this function // is called, serve the next request of the list if (!rtab[next].ll_tail) { next = rtab[index].ll_next; pop_state = NEXT; } // It it is the last element of the list, return to the HEAD state else { pop_state = HEAD; } // Temporarily unset the head bit. This is to prevent the // request to be rescheduled. rtab[index].ll_head = 0; } // Pop the selected request return rtab[index].req; } ``` -------------------------------- ### rtab_find_ready: Find ready linked list head Source: https://openhw-group-cv-hpdcache.readthedocs-hosted.com/architecture.html Searches for a linked list whose head request can be replayed (dependencies resolved). Uses a round-robin policy and returns -1 if no ready entry is found. ```c int rtab_find_ready(int last) { // choose a ready entry using a round-robin policy int i = (last + 1) % RTAB_NENTRIES; for (;;) { // ready entry found if (rtab[i].valid && rtab[i].ll_head && (rtab[i].deps == 0)) return i; // there is no ready entry if (i == last) return -1; i = (i + 1) % RTAB_NENTRIES; } } ``` -------------------------------- ### Allocate and link request in RTAB Source: https://openhw-group-cv-hpdcache.readthedocs-hosted.com/_sources/architecture.rst.txt Allocates a new entry in the RTAB and links it to the tail of an existing request list. ```c int rtab_alloc_and_link(req_t r) { int index = rtab_find_empty(); int match = rtab_match_tail(get_nline(r)); // replace the tail of the linked list rtab[match].ll_tail = 0; // make the next pointer of the old tail to point to the new entry rtab[match].ll_next = index; // add the new request as the tail of the linked list rtab[index] = { valid : 1, deps : 0, ll_head : 0, ll_tail : 1, ll_next : 0, request : r }; return index; } ``` -------------------------------- ### rtab_is_full: Check if RTAB is full Source: https://openhw-group-cv-hpdcache.readthedocs-hosted.com/architecture.html Utility function that returns true if no empty entry is available (i.e., RTAB is full). ```c bool rtab_is_full() { return (rtab_find_empty() == -1); } ``` -------------------------------- ### rtab_is_empty: Check if RTAB is empty Source: https://openhw-group-cv-hpdcache.readthedocs-hosted.com/architecture.html Utility function that returns 1 if no valid entry exists (RTAB empty), otherwise 0. ```c int rtab_is_empty() { for (int i = 0; i < RTAB_NENTRIES; i++) if (rtab[i].valid) return 0; return 1; } ``` -------------------------------- ### RTAB utility functions Source: https://openhw-group-cv-hpdcache.readthedocs-hosted.com/_sources/architecture.rst.txt Utility functions to find empty slots, check if the RTAB is full, or check if it is empty. ```c int rtab_find_empty() { for (int i = 0; i < RTAB_NENTRIES; i++) if (!rtab[i].valid) return i; return -1; } ``` ```c bool rtab_is_full() { return (rtab_find_empty() == -1); } ``` ```c int rtab_is_empty() { for (int i = 0; i < RTAB_NENTRIES; i++) if (rtab[i].valid) return 0; return 1; } ``` -------------------------------- ### RTAB Match Function Source: https://openhw-group-cv-hpdcache.readthedocs-hosted.com/_sources/architecture.rst.txt Matches a request line in the RTAB. ```c int rtab_match(nline_t nline) { for (int i = 0; i < RTAB_NENTRIES; i++) if (rtab[i].valid && get_nline(rtab[i].req) == nline) return i; return -1; } ``` -------------------------------- ### rtab_alloc_and_link: Link a new entry to an existing linked list Source: https://openhw-group-cv-hpdcache.readthedocs-hosted.com/architecture.html Called when a request in the pipeline targets the same cacheline as one or more on-hold requests. Allocates a new entry, finds the tail of the matching linked list, updates the old tail's next pointer, and adds the new entry as the new tail. ```c int rtab_alloc_and_link(req_t r) { int index = rtab_find_empty(); int match = rtab_match_tail(get_nline(r)); // replace the tail of the linked list rtab[match].ll_tail = 0; // make the next pointer of the old tail to point to the new entry rtab[match].ll_next = index; // add the new request as the tail of the linked list rtab[index] = { valid : 1, deps : 0, ll_head : 0, ll_tail : 1, ll_next : 0, request : r }; return index; } ``` -------------------------------- ### rtab_find_empty: Find empty RTAB entry Source: https://openhw-group-cv-hpdcache.readthedocs-hosted.com/architecture.html Utility function that returns the index of the first invalid RTAB entry, or -1 if the RTAB is full. ```c int rtab_find_empty() { for (int i = 0; i < RTAB_NENTRIES; i++) if (!rtab[i].valid) return i; return -1; } ``` -------------------------------- ### Update request dependencies Source: https://openhw-group-cv-hpdcache.readthedocs-hosted.com/_sources/architecture.rst.txt Updates the dependency bits for any request in the RTAB matching the provided cacheline address. ```c void rtab_update_deps(nline_t nline, bitvector deps) { int index = rtab_match(nline); if (index != -1) { rtab[index].deps = deps; } } ``` -------------------------------- ### rtab_match_tail: Match tail request by cacheline Source: https://openhw-group-cv-hpdcache.readthedocs-hosted.com/architecture.html Utility function that finds the index of a valid RTAB entry that is a tail and has the given cacheline address, or -1 if none. ```c int rtab_match_tail(nline_t nline) { for (int i = 0; i < RTAB_NENTRIES; i++) if (rtab[i].valid && get_nline(rtab[i].req) == nline && rtab[i].ll_tail) return i; return -1; } ``` -------------------------------- ### rtab_alloc: Allocate a new linked list entry Source: https://openhw-group-cv-hpdcache.readthedocs-hosted.com/architecture.html Called by the cache controller when a request must be put on hold due to one or more conditions. Allocates an empty entry, sets it as both head and tail of a new linked list, and stores the request and its dependency bits. ```c int rtab_alloc(req_t r, deps_t d) { int index = rtab_find_empty(); rtab[index] = { valid : 1, deps : d, ll_head : 1, ll_tail : 1, ll_next : 0, request : r }; return index; } ``` -------------------------------- ### rtab_match: Match request by cacheline Source: https://openhw-group-cv-hpdcache.readthedocs-hosted.com/architecture.html Utility function that finds the index of a valid RTAB entry with the given cacheline address, or -1 if none. ```c int rtab_match(nline_t nline) { for (int i = 0; i < RTAB_NENTRIES; i++) if (rtab[i].valid && get_nline(rtab[i].req) == nline) return i; return -1; } ``` -------------------------------- ### RTAB Tail Match Function Source: https://openhw-group-cv-hpdcache.readthedocs-hosted.com/_sources/architecture.rst.txt Matches a request line in the RTAB specifically for tail entries. ```c int rtab_match_tail(nline_t nline) { for (int i = 0; i < RTAB_NENTRIES; i++) if (rtab[i].valid && get_nline(rtab[i].req) == nline && rtab[i].ll_tail) return i; return -1; } ``` -------------------------------- ### Declare LRU bit array for PLRU policy Source: https://openhw-group-cv-hpdcache.readthedocs-hosted.com/architecture.html Declares a 2D boolean array for the PLRU state bits, with dimensions CONF_HPDCACHE_SETS and CONF_HPDCACHE_WAYS. All bits are initialized to 0 on reset and updated on each read, CMO prefetch, store, and atomic operation. ```c // 2D array containing LRU state bits bool lru[CONF_HPDCACHE_SETS][CONF_HPDCACHE_WAYS]; ``` -------------------------------- ### rtab_alloc function Source: https://openhw-group-cv-hpdcache.readthedocs-hosted.com/_sources/architecture.rst.txt Allocates a new linked list entry in the RTAB when a request needs to be put on hold. ```c int rtab_alloc(req_t r, deps_t d) { int index = rtab_find_empty(); rtab[index] = { valid : 1, deps : d, ll_head : 1, ll_tail : 1, ll_next : 0, request : r }; return index; } ``` -------------------------------- ### Update PLRU bits with update_plru function Source: https://openhw-group-cv-hpdcache.readthedocs-hosted.com/architecture.html Implements the update_plru algorithm used by the cache controller on read, CMO prefetch, write, and atomic requests. On a hit, it sets the LRU bit for the accessed way; if all bits in the set are 1, it resets all except the accessed way. On a miss, it is applied during refill after victim selection. ```c void update_plru(int set, int way) { // set the LRU bit of the target set and way lru[set][way] = true; // check if all LRU bits of the target "set" contain 1 for (int w = 0; w < HPDCACHE_WAYS; w++) { // If there is at least one 0, the update is done if (!lru[set][w]) return; } // If all LRU bits are set to 1, reset to 0 the LRU bits of all the ways // except the one being accessed for (int w = 0; w < HPDCACHE_WAYS; w++) { if (w != way) lru[set][w] = false; } } ``` -------------------------------- ### rtab_pop_rollback: Restore request with updated deps Source: https://openhw-group-cv-hpdcache.readthedocs-hosted.com/architecture.html Called when a replayed request cannot be retired because one or more on-hold conditions are met. Restores the request into the RTAB with updated dependency bits, keeping its position in the linked list to respect program order. ```c void rtab_pop_rollback(int index, bitvector deps) { rtab[index].ll_head = 1; rtab[index].deps = deps; } ``` -------------------------------- ### Rollback popped request Source: https://openhw-group-cv-hpdcache.readthedocs-hosted.com/_sources/architecture.rst.txt Restores a request into the RTAB with updated dependency bits if it cannot be retired. ```c void rtab_pop_rollback(int index, bitvector deps) { rtab[index].ll_head = 1; rtab[index].deps = deps; } ``` -------------------------------- ### rtab_update_deps: Update dependency bits for matching request Source: https://openhw-group-cv-hpdcache.readthedocs-hosted.com/architecture.html Called by the miss handler and write buffer on completion of a pending transaction. Updates the dependency bits of any matching request (same cacheline address) in the RTAB. ```c void rtab_update_deps(nline_t nline, bitvector deps) { int index = rtab_match(nline); if (index != -1) { rtab[index].deps = deps; } } ``` -------------------------------- ### Commit popped request Source: https://openhw-group-cv-hpdcache.readthedocs-hosted.com/_sources/architecture.rst.txt Marks a request as invalid in the RTAB after it has been successfully processed. ```c void rtab_pop_commit(int index) { rtab[index].valid = 0; } ``` -------------------------------- ### rtab_pop_commit: Mark request as processed Source: https://openhw-group-cv-hpdcache.readthedocs-hosted.com/architecture.html Called when the replayed request is retired. Invalidates the RTAB entry for the given index. ```c void rtab_pop_commit(int index) { rtab[index].valid = 0; } ``` -------------------------------- ### update_plru function in C Source: https://openhw-group-cv-hpdcache.readthedocs-hosted.com/_sources/architecture.rst.txt Updates the PLRU bits for a given set and way. Sets the LRU bit to true, then if all LRU bits in the set are true, resets all except the accessed way. Used on hits and during refill after a miss. ```c void update_plru(int set, int way) { // set the LRU bit of the target set and way lru[set][way] = true; // check if all LRU bits of the target "set" contain 1 for (int w = 0; w < HPDCACHE_WAYS; w++) { // If there is at least one 0, the update is done if (!lru[set][w]) return; } // If all LRU bits are set to 1, reset to 0 the LRU bits of all the ways // except the one being accessed for (int w = 0; w < HPDCACHE_WAYS; w++) { if (w != way) lru[set][w] = false; } } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.