diff options
| -rw-r--r-- | rtl/gfx/gfx_defs.sv | 3 | ||||
| -rw-r--r-- | rtl/gfx/gfx_mem.sv | 118 |
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 |
