summaryrefslogtreecommitdiff
path: root/rtl/gfx/gfx_sp_widener.sv
diff options
context:
space:
mode:
authorAlejandro Soto <alejandro@34project.org>2023-11-19 17:16:58 -0600
committerAlejandro Soto <alejandro@34project.org>2023-11-20 16:46:28 -0600
commit33794ca29db5670bc140686ae6e6d3b7832ad406 (patch)
treec9d66a2aea3d7c725b9b088896e74c6eed751d71 /rtl/gfx/gfx_sp_widener.sv
parent6658a8b5c179682866c89c891b493d05d13a50be (diff)
rtl/gfx: implement SP fetch
Diffstat (limited to 'rtl/gfx/gfx_sp_widener.sv')
-rw-r--r--rtl/gfx/gfx_sp_widener.sv63
1 files changed, 63 insertions, 0 deletions
diff --git a/rtl/gfx/gfx_sp_widener.sv b/rtl/gfx/gfx_sp_widener.sv
new file mode 100644
index 0000000..92101ca
--- /dev/null
+++ b/rtl/gfx/gfx_sp_widener.sv
@@ -0,0 +1,63 @@
+`include "gfx/gfx_defs.sv"
+
+module gfx_sp_widener
+#(parameter WIDTH=0) // Quartus no soporta 'parameter type'
+(
+ input logic clk,
+ rst_n,
+
+ input logic word_waitrequest,
+ word_readdatavalid,
+ input vram_word word_readdata,
+ output vram_addr word_address,
+ output logic word_read,
+
+ input logic wide_read,
+ input logic[WIDTH - 1:0] wide_address,
+ output logic wide_waitrequest,
+ wide_readdatavalid,
+
+ output logic[DATA_WIDTH - 1:0] wide_readdata
+);
+
+ // Este módulo existe para fingir que la DE1-SoC tiene un bus de SDRAM más ancho
+
+ localparam WIDE_BITS = $bits(vram_addr) - WIDTH,
+ WIDE_SIZE = 1 << WIDE_BITS,
+ DATA_WIDTH = $bits(vram_word) << WIDE_BITS;
+
+ vram_word shift_in[WIDE_SIZE];
+ logic[WIDE_BITS - 1:0] address_count, read_count;
+
+ assign word_read = wide_read;
+ assign word_address = {wide_address, address_count};
+ assign wide_waitrequest = word_waitrequest || !(&address_count);
+
+ always_comb
+ for (integer i = 0; i < WIDE_SIZE; ++i)
+ wide_readdata[$bits(vram_word) * i +: $bits(vram_word)] = shift_in[i];
+
+ always_ff @(posedge clk or negedge rst_n)
+ if (!rst_n) begin
+ read_count <= 0;
+ address_count <= 0;
+ wide_readdatavalid <= 0;
+ end else begin
+ if (word_read && !word_waitrequest)
+ address_count <= address_count + 1;
+
+ if (word_readdatavalid)
+ read_count <= read_count + 1;
+
+ wide_readdatavalid <= word_readdatavalid && &read_count;
+ end
+
+ always_ff @(posedge clk)
+ if (word_readdatavalid) begin
+ for (integer i = 0; i < WIDE_SIZE - 1; ++i)
+ shift_in[i] <= shift_in[i + 1];
+
+ shift_in[WIDE_SIZE - 1] <= word_readdata;
+ end
+
+endmodule