summaryrefslogtreecommitdiff
path: root/rtl/gfx
diff options
context:
space:
mode:
authorAlejandro Soto <alejandro@34project.org>2023-11-14 23:06:26 -0600
committerAlejandro Soto <alejandro@34project.org>2023-11-14 23:06:26 -0600
commitebd16f54913aaafd0b6f86223f53fc40b2d64d03 (patch)
tree584dd87eb679071d255b3141db4cc9c363aa9a1e /rtl/gfx
parent8b188d47eab923fb152eae475c86b378d0d5ebee (diff)
rtl/gfx: improve mem timing closure
Diffstat (limited to '')
-rw-r--r--rtl/gfx/gfx_defs.sv3
-rw-r--r--rtl/gfx/gfx_mem.sv118
2 files changed, 90 insertions, 31 deletions
diff --git a/rtl/gfx/gfx_defs.sv b/rtl/gfx/gfx_defs.sv
index e743d75..a9e711e 100644
--- a/rtl/gfx/gfx_defs.sv
+++ b/rtl/gfx/gfx_defs.sv
@@ -158,7 +158,8 @@ typedef struct packed
`define GFX_MEM_DATA_BITS 16 // No puedo hacer nada al respecto
`define GFX_MEM_SUBWORD_BITS ($clog2(`GFX_MEM_DATA_BITS / 8))
`define GFX_MEM_ADDR_BITS (`GFX_MEM_WORD_ADDR_BITS + `GFX_MEM_SUBWORD_BITS)
-`define GFX_MEM_FIFO_DEPTH 8 // Ajustar
+`define GFX_MEM_FIFO_DEPTH 4 // Ajustar
+`define GFX_MEM_TRANS_DEPTH 4 // Ajustar
typedef logic[`GFX_MEM_DATA_BITS - 1:0] mem_word;
typedef logic[`GFX_MEM_ADDR_BITS - 1:0] mem_addr;
diff --git a/rtl/gfx/gfx_mem.sv b/rtl/gfx/gfx_mem.sv
index 4b671be..a4cf240 100644
--- a/rtl/gfx/gfx_mem.sv
+++ b/rtl/gfx/gfx_mem.sv
@@ -27,44 +27,102 @@ module gfx_mem
// Esto está mal, hay que reescribirlo totalmente
- logic lock, lock_rop, select_rop, wait_state;
-
- assign fb_readdata = mem_readdata;
- assign fb_readdatavalid = mem_readdatavalid;
-
- assign mem_writedata = rop_writedata;
-
- assign wait_state = (mem_read || mem_write) && mem_waitrequest;
+ logic mem_rw, trans_in_stall, trans_out_stall, in_ready, skid_in_valid, out_ready;
+
+ struct packed
+ {
+ mem_addr address;
+ logic write;
+ mem_word writedata;
+ } trans_in, trans_out, trans_in_skid, trans_out_skid;
+
+ /* Cerrar timing aquí no es tan fácil, debido al enrutamiento al el que
+ * necesariamente está sujeto este módulo (eg, VRAM y DAC están en
+ * posiciones fijas en los bordes de la FPGA y no pueden reacomodarse).
+ */
+
+ gfx_skid_buf #(.WIDTH($bits(trans_in))) in_skid
+ (
+ .in(trans_in),
+ .out(trans_in_skid),
+ .stall(trans_in_stall),
+ .*
+ );
+
+ gfx_skid_flow in_flow
+ (
+ .stall(trans_in_stall),
+ .in_ready(in_ready),
+ .in_valid(rop_write || fb_read),
+ .out_ready(out_ready),
+ .out_valid(skid_in_valid),
+ .*
+ );
+
+ gfx_pipes #(.WIDTH($bits(trans_out)), .DEPTH(`GFX_MEM_TRANS_DEPTH)) out_pipes
+ (
+ .in(trans_in_skid),
+ .out(trans_out),
+ .stall(trans_out_stall),
+ .*
+ );
+
+ gfx_skid_buf #(.WIDTH($bits(trans_out))) out_skid
+ (
+ .in(trans_out),
+ .out(trans_out_skid),
+ .stall(trans_out_stall),
+ .*
+ );
+
+ gfx_pipeline_flow #(.STAGES(`GFX_MEM_TRANS_DEPTH)) out_flow
+ (
+ .stall(trans_out_stall),
+ .in_ready(out_ready),
+ .in_valid(skid_in_valid),
+ .out_ready(!mem_waitrequest),
+ .out_valid(mem_rw),
+ .*
+ );
+
+ gfx_pipes #(.WIDTH($bits(mem_word)), .DEPTH(`GFX_MEM_FIFO_DEPTH)) readdata_pipes
+ (
+ .in(mem_readdata),
+ .out(fb_readdata),
+ .stall(0),
+ .*
+ );
+
+ gfx_pipeline_flow #(.STAGES(`GFX_MEM_FIFO_DEPTH)) readdata_flow
+ (
+ .stall(),
+ .in_ready(),
+ .in_valid(mem_readdatavalid),
+ .out_ready(1),
+ .out_valid(fb_readdatavalid),
+ .*
+ );
+
+ assign mem_read = mem_rw && !trans_out_skid.write;
+ assign mem_write = mem_rw && trans_out_skid.write;
+ assign mem_address = trans_out_skid.address;
+ assign mem_writedata = trans_out_skid.writedata;
always_comb begin
- select_rop = !fb_read;
-
- if (lock)
- select_rop = lock_rop;
-
- mem_read = 0;
- mem_write = 0;
fb_waitrequest = 1;
rop_waitrequest = 1;
- if (select_rop) begin
- mem_write = rop_write;
- mem_address = {6'd0, rop_address};
+ trans_in.writedata = rop_writedata;
- rop_waitrequest = mem_waitrequest;
+ if (fb_read) begin
+ fb_waitrequest = !in_ready;
+ trans_in.write = 0;
+ trans_in.address = {6'd0, fb_address};
end else begin
- mem_read = fb_read;
- mem_address = {6'd0, fb_address};
-
- fb_waitrequest = mem_waitrequest;
+ rop_waitrequest = !in_ready;
+ trans_in.write = 1;
+ trans_in.address = {6'd0, rop_address};
end
end
- always_ff @(posedge clk or negedge rst_n)
- lock <= !rst_n ? 0 : wait_state;
-
- always_ff @(posedge clk)
- if (wait_state)
- lock_rop <= select_rop;
-
endmodule