summaryrefslogtreecommitdiff
path: root/hdl/mem_arbiter.sv
diff options
context:
space:
mode:
Diffstat (limited to 'hdl/mem_arbiter.sv')
-rw-r--r--hdl/mem_arbiter.sv79
1 files changed, 79 insertions, 0 deletions
diff --git a/hdl/mem_arbiter.sv b/hdl/mem_arbiter.sv
new file mode 100644
index 0000000..ba3bd7d
--- /dev/null
+++ b/hdl/mem_arbiter.sv
@@ -0,0 +1,79 @@
1`include "defs.svh"
2
3module mem_arbiter
4 ( input bit clock
5 , input bit reset
6
7 , output bit command_ready
8 , input bit command_valid
9 , input ram_command_t command_data
10
11 , output bit [`NUM_PDPS-1:0] pdp_ready
12 , input bit [`NUM_PDPS-1:0] pdp_valid
13 , input pdp_command_t [`NUM_PDPS-1:0] pdp_data
14
15 , input bit ram_ready
16 , output bit ram_valid
17 , output ram_command_t ram_data
18 );
19
20 bit [`NUM_PDPS:0] hold_valid;
21 ram_command_t [`NUM_PDPS:0] hold_data;
22
23 bit [$clog2(`NUM_PDPS+1):0] selector;
24
25 always @(posedge clock) begin
26 if (reset) begin
27 command_ready = 0;
28 for (int i = 0; i < `NUM_PDPS; ++i)
29 pdp_ready[i] = 0;
30 ram_valid = 0;
31 for (int i = 0; i < `NUM_PDPS+1; ++i)
32 hold_valid[i] = 0;
33 selector = 0;
34 end else begin
35 automatic bit ram_was_valid = ram_valid;
36
37 if (ram_ready) ram_valid = 0;
38
39 if (command_ready && command_valid) begin
40 hold_valid[0] = 1;
41 hold_data[0] = command_data;
42 hold_data[0].tag = 0;
43 end
44 for (int i = 0; i < `NUM_PDPS; ++i) begin
45 if (pdp_ready[i] && pdp_valid[i]) begin
46 hold_valid[i+1] = 1;
47 hold_data[i+1].address[`RAM_ADDRESS_BITS-1:`PDP_ADDRESS_BITS] = i;
48 hold_data[i+1].address[`PDP_ADDRESS_BITS-1:$clog2(`RAM_LINE_WORDS)] = pdp_data[i].address;
49 hold_data[i+1].write = pdp_data[i].write;
50 hold_data[i+1].data = pdp_data[i].data;
51 hold_data[i+1].mask = pdp_data[i].mask;
52 hold_data[i+1].tag = i+1;
53 end
54 end
55
56 for (int i = 0; i < `NUM_PDPS+1; ++i) begin
57 automatic int j = selector + i;
58 if (j > `NUM_PDPS) j = j - `NUM_PDPS-1;
59 if (!ram_valid && hold_valid[j]) begin
60 ram_valid = 1;
61 ram_data = hold_data[j];
62 hold_valid[j] = 0;
63 end
64 end
65
66 if (ram_valid && !ram_was_valid) begin
67 if (selector == `NUM_PDPS)
68 selector = 0;
69 else
70 ++selector;
71 end
72
73 command_ready = !hold_valid[0];
74 for (int i = 0; i < `NUM_PDPS; ++i)
75 pdp_ready[i] = !hold_valid[i+1];
76 end
77 end
78
79endmodule