summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulian Blake Kongslie2022-03-13 16:50:34 -0700
committerJulian Blake Kongslie2022-03-13 16:50:34 -0700
commitfce46a9a7bb2fe2a9b3addca0f488931b9e231ff (patch)
tree31a467115e726b0b0e79b8ae7dbe91c0472a6295
parentFix DRAM timings to avoid back-to-back transactions. (diff)
downloadmultipdp8-fce46a9a7bb2fe2a9b3addca0f488931b9e231ff.tar.xz
Add memory arbiter and broadcast in between command UART and DRAM.
-rw-r--r--hdl/mem_arbiter.sv79
-rw-r--r--hdl/mem_broadcast.sv61
-rw-r--r--hdl/top.sv80
3 files changed, 203 insertions, 17 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
diff --git a/hdl/mem_broadcast.sv b/hdl/mem_broadcast.sv
new file mode 100644
index 0000000..720699b
--- /dev/null
+++ b/hdl/mem_broadcast.sv
@@ -0,0 +1,61 @@
1`include "defs.svh"
2
3module mem_broadcast
4 ( input bit clock
5 , input bit reset
6
7 , output bit ram_ready
8 , input bit ram_valid
9 , input ram_read_response_t ram_data
10
11 , input bit print_ready
12 , output bit print_valid
13 , output ram_read_response_t print_data
14
15 , input bit [`NUM_PDPS-1:0] pdp_ready
16 , output bit [`NUM_PDPS-1:0] pdp_valid
17 , output pdp_read_response_t [`NUM_PDPS-1:0] pdp_data
18 );
19
20 bit hold_valid;
21 ram_read_response_t hold_data;
22
23 always @(posedge clock) begin
24 if (reset) begin
25 ram_ready = 0;
26 print_valid = 0;
27 for (int i = 0; i < `NUM_PDPS; ++i)
28 pdp_valid[i] = 0;
29 hold_valid = 0;
30 end else begin
31 if (print_ready) print_valid = 0;
32 for (int i = 0; i < `NUM_PDPS; ++i)
33 if (pdp_ready[i]) pdp_valid[i] = 0;
34
35 if (ram_ready && ram_valid) begin
36 hold_valid = 1;
37 hold_data = ram_data;
38 end
39
40 if (hold_valid) begin
41 if (hold_data.tag == 0) begin
42 if (!print_valid) begin
43 print_valid = 1;
44 print_data = hold_data;
45 hold_valid = 0;
46 end
47 end else begin
48 if (!pdp_valid[ram_data.tag-1]) begin
49 pdp_valid[ram_data.tag-1] = 1;
50 pdp_data[ram_data.tag-1].address = hold_data.address[`PDP_ADDRESS_BITS-1:$clog2(`RAM_LINE_WORDS)];
51 pdp_data[ram_data.tag-1].data = hold_data.data;
52 hold_valid = 0;
53 end
54 end
55 end
56
57 ram_ready = !hold_valid;
58 end
59 end
60
61endmodule
diff --git a/hdl/top.sv b/hdl/top.sv
index 5c8b531..ba6311f 100644
--- a/hdl/top.sv
+++ b/hdl/top.sv
@@ -48,9 +48,25 @@ module top
48 bit command_valid; 48 bit command_valid;
49 ram_command_t command_data; 49 ram_command_t command_data;
50 50
51 bit result_ready; 51 bit ram_command_ready;
52 bit result_valid; 52 bit ram_command_valid;
53 ram_read_response_t result_data; 53 ram_command_t ram_command_data;
54
55 bit ram_response_ready;
56 bit ram_response_valid;
57 ram_read_response_t ram_response_data;
58
59 bit print_ready;
60 bit print_valid;
61 ram_read_response_t print_data;
62
63 bit [`NUM_PDPS-1:0] pdp_command_ready;
64 bit [`NUM_PDPS-1:0] pdp_command_valid;
65 pdp_command_t [`NUM_PDPS-1:0] pdp_command_data;
66
67 bit [`NUM_PDPS-1:0] pdp_response_ready;
68 bit [`NUM_PDPS-1:0] pdp_response_valid;
69 pdp_read_response_t [`NUM_PDPS-1:0] pdp_response_data;
54 70
55 bit ram_rwds_oe; 71 bit ram_rwds_oe;
56 bit ram_rwds_out; 72 bit ram_rwds_out;
@@ -78,7 +94,7 @@ module top
78 , .t_ena(ram_rx_valid) 94 , .t_ena(ram_rx_valid)
79 ); 95 );
80 96
81 echo_arbiter arb 97 echo_arbiter uart0arb
82 ( .clock(internal_clock) 98 ( .clock(internal_clock)
83 , .reset(internal_reset) 99 , .reset(internal_reset)
84 100
@@ -95,9 +111,7 @@ module top
95 , .out_data(ram_tx_data) 111 , .out_data(ram_tx_data)
96 ); 112 );
97 113
98 command_parser 114 command_parser parser
99 #( .TAG(0)
100 ) parser
101 ( .clock(internal_clock) 115 ( .clock(internal_clock)
102 , .reset(internal_reset) 116 , .reset(internal_reset)
103 117
@@ -114,7 +128,7 @@ module top
114 , .command_data(command_data) 128 , .command_data(command_data)
115 ); 129 );
116 130
117 ram_controller ram 131 mem_arbiter memarb
118 ( .clock(internal_clock) 132 ( .clock(internal_clock)
119 , .reset(internal_reset) 133 , .reset(internal_reset)
120 134
@@ -122,9 +136,26 @@ module top
122 , .command_valid(command_valid) 136 , .command_valid(command_valid)
123 , .command_data(command_data) 137 , .command_data(command_data)
124 138
125 , .result_ready(result_ready) 139 , .pdp_ready(pdp_command_ready)
126 , .result_valid(result_valid) 140 , .pdp_valid(pdp_command_valid)
127 , .result_data(result_data) 141 , .pdp_data(pdp_command_data)
142
143 , .ram_ready(ram_command_ready)
144 , .ram_valid(ram_command_valid)
145 , .ram_data(ram_command_data)
146 );
147
148 ram_controller ram
149 ( .clock(internal_clock)
150 , .reset(internal_reset)
151
152 , .command_ready(ram_command_ready)
153 , .command_valid(ram_command_valid)
154 , .command_data(ram_command_data)
155
156 , .result_ready(ram_response_ready)
157 , .result_valid(ram_response_valid)
158 , .result_data(ram_response_data)
128 159
129 , .ram_resetn(ram_resetn) 160 , .ram_resetn(ram_resetn)
130 , .ram_csn(ram_csn) 161 , .ram_csn(ram_csn)
@@ -138,15 +169,30 @@ module top
138 , .ram_data_out(ram_data_out) 169 , .ram_data_out(ram_data_out)
139 ); 170 );
140 171
141 result_printer 172 mem_broadcast memcast
142 #( .TAG(0) 173 ( .clock(internal_clock)
143 ) print 174 , .reset(internal_reset)
175
176 , .ram_ready(ram_response_ready)
177 , .ram_valid(ram_response_valid)
178 , .ram_data(ram_response_data)
179
180 , .print_ready(print_ready)
181 , .print_valid(print_valid)
182 , .print_data(print_data)
183
184 , .pdp_ready(pdp_response_ready)
185 , .pdp_valid(pdp_response_valid)
186 , .pdp_data(pdp_response_data)
187 );
188
189 result_printer print
144 ( .clock(internal_clock) 190 ( .clock(internal_clock)
145 , .reset(internal_reset) 191 , .reset(internal_reset)
146 192
147 , .result_ready(result_ready) 193 , .result_ready(print_ready)
148 , .result_valid(result_valid) 194 , .result_valid(print_valid)
149 , .result_data(result_data) 195 , .result_data(print_data)
150 196
151 , .echo_ready(ram_echo_in1_ready) 197 , .echo_ready(ram_echo_in1_ready)
152 , .echo_valid(ram_echo_in1_valid) 198 , .echo_valid(ram_echo_in1_valid)