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 +++++++++++++++++++++++++++++++++++++++++++++++++++ hdl/mem_broadcast.sv | 61 +++++++++++++++++++++++++++++++++++++++ hdl/top.sv | 80 +++++++++++++++++++++++++++++++++++++++++----------- 3 files changed, 203 insertions(+), 17 deletions(-) create mode 100644 hdl/mem_arbiter.sv create mode 100644 hdl/mem_broadcast.sv (limited to 'hdl') 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 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 @@ +`include "defs.svh" + +module mem_broadcast + ( input bit clock + , input bit reset + + , output bit ram_ready + , input bit ram_valid + , input ram_read_response_t ram_data + + , input bit print_ready + , output bit print_valid + , output ram_read_response_t print_data + + , input bit [`NUM_PDPS-1:0] pdp_ready + , output bit [`NUM_PDPS-1:0] pdp_valid + , output pdp_read_response_t [`NUM_PDPS-1:0] pdp_data + ); + + bit hold_valid; + ram_read_response_t hold_data; + + always @(posedge clock) begin + if (reset) begin + ram_ready = 0; + print_valid = 0; + for (int i = 0; i < `NUM_PDPS; ++i) + pdp_valid[i] = 0; + hold_valid = 0; + end else begin + if (print_ready) print_valid = 0; + for (int i = 0; i < `NUM_PDPS; ++i) + if (pdp_ready[i]) pdp_valid[i] = 0; + + if (ram_ready && ram_valid) begin + hold_valid = 1; + hold_data = ram_data; + end + + if (hold_valid) begin + if (hold_data.tag == 0) begin + if (!print_valid) begin + print_valid = 1; + print_data = hold_data; + hold_valid = 0; + end + end else begin + if (!pdp_valid[ram_data.tag-1]) begin + pdp_valid[ram_data.tag-1] = 1; + pdp_data[ram_data.tag-1].address = hold_data.address[`PDP_ADDRESS_BITS-1:$clog2(`RAM_LINE_WORDS)]; + pdp_data[ram_data.tag-1].data = hold_data.data; + hold_valid = 0; + end + end + end + + ram_ready = !hold_valid; + end + end + +endmodule 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 bit command_valid; ram_command_t command_data; - bit result_ready; - bit result_valid; - ram_read_response_t result_data; + bit ram_command_ready; + bit ram_command_valid; + ram_command_t ram_command_data; + + bit ram_response_ready; + bit ram_response_valid; + ram_read_response_t ram_response_data; + + bit print_ready; + bit print_valid; + ram_read_response_t print_data; + + bit [`NUM_PDPS-1:0] pdp_command_ready; + bit [`NUM_PDPS-1:0] pdp_command_valid; + pdp_command_t [`NUM_PDPS-1:0] pdp_command_data; + + bit [`NUM_PDPS-1:0] pdp_response_ready; + bit [`NUM_PDPS-1:0] pdp_response_valid; + pdp_read_response_t [`NUM_PDPS-1:0] pdp_response_data; bit ram_rwds_oe; bit ram_rwds_out; @@ -78,7 +94,7 @@ module top , .t_ena(ram_rx_valid) ); - echo_arbiter arb + echo_arbiter uart0arb ( .clock(internal_clock) , .reset(internal_reset) @@ -95,9 +111,7 @@ module top , .out_data(ram_tx_data) ); - command_parser - #( .TAG(0) - ) parser + command_parser parser ( .clock(internal_clock) , .reset(internal_reset) @@ -114,7 +128,7 @@ module top , .command_data(command_data) ); - ram_controller ram + mem_arbiter memarb ( .clock(internal_clock) , .reset(internal_reset) @@ -122,9 +136,26 @@ module top , .command_valid(command_valid) , .command_data(command_data) - , .result_ready(result_ready) - , .result_valid(result_valid) - , .result_data(result_data) + , .pdp_ready(pdp_command_ready) + , .pdp_valid(pdp_command_valid) + , .pdp_data(pdp_command_data) + + , .ram_ready(ram_command_ready) + , .ram_valid(ram_command_valid) + , .ram_data(ram_command_data) + ); + + ram_controller ram + ( .clock(internal_clock) + , .reset(internal_reset) + + , .command_ready(ram_command_ready) + , .command_valid(ram_command_valid) + , .command_data(ram_command_data) + + , .result_ready(ram_response_ready) + , .result_valid(ram_response_valid) + , .result_data(ram_response_data) , .ram_resetn(ram_resetn) , .ram_csn(ram_csn) @@ -138,15 +169,30 @@ module top , .ram_data_out(ram_data_out) ); - result_printer - #( .TAG(0) - ) print + mem_broadcast memcast + ( .clock(internal_clock) + , .reset(internal_reset) + + , .ram_ready(ram_response_ready) + , .ram_valid(ram_response_valid) + , .ram_data(ram_response_data) + + , .print_ready(print_ready) + , .print_valid(print_valid) + , .print_data(print_data) + + , .pdp_ready(pdp_response_ready) + , .pdp_valid(pdp_response_valid) + , .pdp_data(pdp_response_data) + ); + + result_printer print ( .clock(internal_clock) , .reset(internal_reset) - , .result_ready(result_ready) - , .result_valid(result_valid) - , .result_data(result_data) + , .result_ready(print_ready) + , .result_valid(print_valid) + , .result_data(print_data) , .echo_ready(ram_echo_in1_ready) , .echo_valid(ram_echo_in1_valid) -- cgit v1.2.3