This repository was archived by the owner on Jul 3, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathls-queue.c
More file actions
98 lines (89 loc) · 2.7 KB
/
Copy pathls-queue.c
File metadata and controls
98 lines (89 loc) · 2.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
#include <assert.h>
#include <stdlib.h>
#include "clk.h"
#include "lib/closure.h"
#include "ls-queue.h"
#include "lib/log.h"
#include "memory.h"
#include "queue.h"
#include "reg.h"
#include "rv32i.h"
#define LS_QUEUE_CAPACITY 8
void _ls_queue_tick (void *state, va_list args) {
ls_queue_t *queue = (ls_queue_t *) state;
if (*rm_read(queue->clear, bool)) {
reg_mut_t *reg;
queue_foreach (queue->queue, i, reg) {
if (rm_read(reg, ls_queue_payload_t)->op == LS_LOAD) {
rm_write(reg, ls_queue_payload_t).cleared = true;
}
}
return;
}
if (busy_wait_should_stall(queue->lock)) {
debug_log("ls queue busy waiting");
return;
}
if (queue_empty(queue->queue)) {
debug_log("ls queue empty, skipping");
return;
}
const ls_queue_payload_t *data =
rm_read(queue_pop(queue->queue), ls_queue_payload_t);
if (data->cleared) return;
switch (data->op) {
case LS_LOAD:
debug_log("ls queue load addr %08x for ROB #%02d",
data->addr, data->base_msg.rob);
mem_request_load(queue->mem, data->addr, data->size,
data->base_msg);
break;
case LS_STORE:
debug_log("ls queue store addr %08x value %08x",
data->addr, data->value);
mem_request_store(queue->mem, data->addr, data->value,
data->size,
busy_wait_callback(queue->lock));
busy_wait(queue->lock);
break;
default:
debug_log("unknown ls queue op %d", data->op);
assert(false);
}
}
ls_queue_t *ls_queue_create (memory_t *mem, clk_t *clk) {
ls_queue_t *queue =
(ls_queue_t *) malloc(sizeof(ls_queue_t));
queue->queue = queue_create(LS_QUEUE_CAPACITY,
sizeof(ls_queue_payload_t),
clk);
queue->lock = busy_wait_create(clk);
queue->clear = reg_mut_create(sizeof(bool), clk);
queue->clear->clear = true;
queue->mem = mem;
clk_add_callback(clk, closure_create(_ls_queue_tick, queue));
return queue;
}
void ls_queue_free (ls_queue_t *queue) {
queue_free(queue->queue);
busy_wait_free(queue->lock);
reg_mut_free(queue->clear);
free(queue);
}
bool ls_queue_full (ls_queue_t *queue) {
return queue_full(queue->queue);
}
status_t ls_queue_push (ls_queue_t *queue,
ls_queue_payload_t payload) {
if (ls_queue_full(queue)) return STATUS_FAIL;
reg_mut_t *reg = queue_push(queue->queue);
payload.cleared = false;
rm_write(reg, ls_queue_payload_t) = payload;
debug_log("recv req %s addr %08x size %d",
payload.op == LS_LOAD ? "load" : "store",
payload.addr, payload.size);
return STATUS_SUCCESS;
}
void ls_queue_clear (ls_queue_t *queue) {
rm_write(queue->clear, bool) = true;
}