diff options
| author | Alejandro Soto <alejandro@34project.org> | 2024-05-05 17:34:22 -0600 |
|---|---|---|
| committer | Alejandro Soto <alejandro@34project.org> | 2024-05-05 17:38:27 -0600 |
| commit | 081a8a3ba8bfe036f31da53f9c041a2caa30fce2 (patch) | |
| tree | 7d712b67d3dc1ad3d37041562774ba3c4e5a7f49 /rtl/legacy_gfx/gfx_mem.sv | |
| parent | e5b64ea353678baabd16d245fcfaa3384e1acf8f (diff) | |
rtl/legacy_gfx: rename gfx -> legacy_gfx
Diffstat (limited to 'rtl/legacy_gfx/gfx_mem.sv')
| -rw-r--r-- | rtl/legacy_gfx/gfx_mem.sv | 228 |
1 files changed, 228 insertions, 0 deletions
diff --git a/rtl/legacy_gfx/gfx_mem.sv b/rtl/legacy_gfx/gfx_mem.sv new file mode 100644 index 0000000..fbca2fa --- /dev/null +++ b/rtl/legacy_gfx/gfx_mem.sv @@ -0,0 +1,228 @@ +`include "gfx/gfx_defs.sv" + +module gfx_mem +( + input logic clk, + rst_n, + + input logic mem_waitrequest, + mem_readdatavalid, + input vram_word mem_readdata, + output vram_byte_addr mem_address, + output logic mem_read, + mem_write, + output vram_word mem_writedata, + + input vram_addr host_address, + input logic host_read, + host_write, + input vram_word host_writedata, + output logic host_waitrequest, + host_readdatavalid, + output vram_word host_readdata, + + input logic rop_write, + input vram_word rop_writedata, + input vram_addr rop_address, + output logic rop_waitrequest, + + input logic fb_read, + input vram_addr fb_address, + output logic fb_waitrequest, + fb_readdatavalid, + output vram_word fb_readdata, + + input logic batch_read, + input vram_addr batch_address, + output logic batch_waitrequest, + batch_readdatavalid, + output vram_word batch_readdata, + + input logic fetch_read, + input vram_addr fetch_address, + output logic fetch_waitrequest, + fetch_readdatavalid, + output vram_word fetch_readdata +); + + // Este módulo es inaceptable, hay que reescribirlo + + logic mem_rw, trans_in_stall, trans_out_stall, in_ready, in_valid, skid_in_valid, out_ready, + any_readdatavalid, readdatavalid, dispatch_full, dispatch_put, mem_ready; + + vram_word any_readdata, readdata; + logic[$clog2(`GFX_MEM_DISPATCH_DEPTH) - 1:0] next_put_ptr, pop_ptr, put_ptr; + + struct packed + { + logic fb, + host, + batch, + fetch; + } dispatch_in, dispatch_out, dispatch_buf[`GFX_MEM_DISPATCH_DEPTH]; + + struct packed + { + vram_addr address; + logic write, + fb_waitrequest, + host_waitrequest, + batch_waitrequest, + fetch_waitrequest; + vram_word writedata; + } trans_in, trans_out, trans_in_skid, trans_out_skid; + + assign mem_read = mem_rw && !trans_out_skid.write && !dispatch_full; + assign mem_write = mem_rw && trans_out_skid.write; + assign mem_address = {trans_out_skid.address, {`GFX_MEM_SUBWORD_BITS{1'b0}}}; + assign mem_writedata = trans_out_skid.writedata; + + assign fb_readdata = any_readdata; + assign host_readdata = any_readdata; + assign batch_readdata = any_readdata; + assign fetch_readdata = any_readdata; + + assign fb_readdatavalid = any_readdatavalid && dispatch_out.fb; + assign host_readdatavalid = any_readdatavalid && dispatch_out.host; + assign batch_readdatavalid = any_readdatavalid && dispatch_out.batch; + assign fetch_readdatavalid = any_readdatavalid && dispatch_out.fetch; + + assign dispatch_in.fb = !trans_out_skid.fb_waitrequest; + assign dispatch_in.host = !trans_out_skid.host_waitrequest; + assign dispatch_in.batch = !trans_out_skid.batch_waitrequest; + assign dispatch_in.fetch = !trans_out_skid.fetch_waitrequest; + + assign in_valid = rop_write || fb_read || batch_read || fetch_read || host_read || host_write; + assign mem_ready = !mem_waitrequest && (!dispatch_full || trans_out_skid.write); + assign next_put_ptr = put_ptr + 1; + assign dispatch_put = mem_ready && mem_rw && !trans_out_skid.write; + assign dispatch_full = next_put_ptr == pop_ptr; + + /* 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), + .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_ready), + .out_valid(mem_rw), + .* + ); + + gfx_pipes #(.WIDTH($bits(vram_word)), .DEPTH(`GFX_MEM_RESPONSE_DEPTH)) readdata_pipes + ( + .in(mem_readdata), + .out(readdata), + .stall(0), + .* + ); + + gfx_pipeline_flow #(.STAGES(`GFX_MEM_RESPONSE_DEPTH)) readdata_flow + ( + .stall(), + .in_ready(), + .in_valid(mem_readdatavalid), + .out_ready(1), + .out_valid(readdatavalid), + .* + ); + + always_comb begin + fb_waitrequest = 1; + rop_waitrequest = 1; + host_waitrequest = 1; + batch_waitrequest = 1; + fetch_waitrequest = 1; + + trans_in.write = 0; + trans_in.writedata = {($bits(trans_in.writedata)){1'bx}}; + + if (fb_read) begin + fb_waitrequest = !in_ready; + trans_in.address = fb_address; + end else if (batch_read) begin + batch_waitrequest = !in_ready; + trans_in.address = batch_address; + end else if (rop_write) begin + rop_waitrequest = !in_ready; + + trans_in.write = 1; + trans_in.address = rop_address; + trans_in.writedata = rop_writedata; + end else if (fetch_read) begin + fetch_waitrequest = !in_ready; + trans_in.address = fetch_address; + end else begin + host_waitrequest = !in_ready; + + trans_in.write = host_write; + trans_in.address = host_address; + trans_in.writedata = host_writedata; + end + + trans_in.fb_waitrequest = fb_waitrequest; + trans_in.host_waitrequest = host_waitrequest; + trans_in.batch_waitrequest = batch_waitrequest; + trans_in.fetch_waitrequest = fetch_waitrequest; + end + + always_ff @(posedge clk or negedge rst_n) + if (!rst_n) begin + pop_ptr <= 0; + put_ptr <= 0; + end else begin + if (readdatavalid) + pop_ptr <= pop_ptr + 1; + + if (dispatch_put) + put_ptr <= next_put_ptr; + end + + + always_ff @(posedge clk) begin + any_readdata <= readdata; + any_readdatavalid <= readdatavalid; + + dispatch_out <= dispatch_buf[pop_ptr]; + + if (dispatch_put) + dispatch_buf[put_ptr] <= dispatch_in; + end + +endmodule |
