From fce46a9a7bb2fe2a9b3addca0f488931b9e231ff Mon Sep 17 00:00:00 2001 From: Julian Blake Kongslie Date: Sun, 13 Mar 2022 16:50:34 -0700 Subject: Add memory arbiter and broadcast in between command UART and DRAM. --- hdl/mem_arbiter.sv | 79 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) create mode 100644 hdl/mem_arbiter.sv (limited to 'hdl/mem_arbiter.sv') 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 @@ +`include "defs.svh" + +module mem_arbiter + ( input bit clock + , input bit reset + + , output bit command_ready + , input bit command_valid + , input ram_command_t command_data + + , output bit [`NUM_PDPS-1:0] pdp_ready + , input bit [`NUM_PDPS-1:0] pdp_valid + , input pdp_command_t [`NUM_PDPS-1:0] pdp_data + + , input bit ram_ready + , output bit ram_valid + , output ram_command_t ram_data + ); + + bit [`NUM_PDPS:0] hold_valid; + ram_command_t [`NUM_PDPS:0] hold_data; + + bit [$clog2(`NUM_PDPS+1):0] selector; + + always @(posedge clock) begin + if (reset) begin + command_ready = 0; + for (int i = 0; i < `NUM_PDPS; ++i) + pdp_ready[i] = 0; + ram_valid = 0; + for (int i = 0; i < `NUM_PDPS+1; ++i) + hold_valid[i] = 0; + selector = 0; + end else begin + automatic bit ram_was_valid = ram_valid; + + if (ram_ready) ram_valid = 0; + + if (command_ready && command_valid) begin + hold_valid[0] = 1; + hold_data[0] = command_data; + hold_data[0].tag = 0; + end + for (int i = 0; i < `NUM_PDPS; ++i) begin + if (pdp_ready[i] && pdp_valid[i]) begin + hold_valid[i+1] = 1; + hold_data[i+1].address[`RAM_ADDRESS_BITS-1:`PDP_ADDRESS_BITS] = i; + hold_data[i+1].address[`PDP_ADDRESS_BITS-1:$clog2(`RAM_LINE_WORDS)] = pdp_data[i].address; + hold_data[i+1].write = pdp_data[i].write; + hold_data[i+1].data = pdp_data[i].data; + hold_data[i+1].mask = pdp_data[i].mask; + hold_data[i+1].tag = i+1; + end + end + + for (int i = 0; i < `NUM_PDPS+1; ++i) begin + automatic int j = selector + i; + if (j > `NUM_PDPS) j = j - `NUM_PDPS-1; + if (!ram_valid && hold_valid[j]) begin + ram_valid = 1; + ram_data = hold_data[j]; + hold_valid[j] = 0; + end + end + + if (ram_valid && !ram_was_valid) begin + if (selector == `NUM_PDPS) + selector = 0; + else + ++selector; + end + + command_ready = !hold_valid[0]; + for (int i = 0; i < `NUM_PDPS; ++i) + pdp_ready[i] = !hold_valid[i+1]; + end + end + +endmodule -- cgit v1.2.3