From ce34e3dfb0fc38a5763f5b81360f35e6e880df91 Mon Sep 17 00:00:00 2001 From: Alejandro Soto Date: Sun, 19 Nov 2023 20:54:04 -0600 Subject: rtl/gfx: factor FIFO overflow logic --- rtl/gfx/gfx_fifo_overflow.sv | 34 +++++++++++++++ rtl/gfx/gfx_sp_batch.sv | 53 +++++++++++------------ rtl/gfx/gfx_sp_fetch.sv | 100 +++++++++++++++++++++---------------------- 3 files changed, 108 insertions(+), 79 deletions(-) create mode 100644 rtl/gfx/gfx_fifo_overflow.sv (limited to 'rtl') diff --git a/rtl/gfx/gfx_fifo_overflow.sv b/rtl/gfx/gfx_fifo_overflow.sv new file mode 100644 index 0000000..c9cb3de --- /dev/null +++ b/rtl/gfx/gfx_fifo_overflow.sv @@ -0,0 +1,34 @@ +`include "gfx/gfx_defs.sv" + +module gfx_fifo_overflow +#(parameter DEPTH=0) +( + input logic clk, + rst_n, + + input logic down, + out_ready, + out_valid, + + output logic empty, + down_safe +); + + logic up; + logic[$clog2(DEPTH + 1) - 1:0] pending; + + assign up = out_ready && out_valid; + assign empty = pending == 0; + assign down_safe = up || pending < DEPTH - 1; + + always_ff @(posedge clk or negedge rst_n) + if (!rst_n) + pending <= 0; + else begin + if (up && !down) + pending <= pending - 1; + else if (!up && down) + pending <= pending + 1; + end + +endmodule diff --git a/rtl/gfx/gfx_sp_batch.sv b/rtl/gfx/gfx_sp_batch.sv index 9c2c503..a2c13ee 100644 --- a/rtl/gfx/gfx_sp_batch.sv +++ b/rtl/gfx/gfx_sp_batch.sv @@ -24,12 +24,11 @@ module gfx_sp_batch localparam TAIL_BITS = $clog2($bits(lane_mask)), BLOCK_BITS = $bits(batch_length) - TAIL_BITS; - logic fifo_down, fifo_up, lane_read, lane_readdatavalid, lane_waitrequest; + logic fifo_down_safe, lane_read, lane_readdatavalid, lane_waitrequest; lane_word lane_readdata; vram_lane_addr aligned_batch_base, lane_address; logic[TAIL_BITS - 1:0] batch_length_tail, read_tail; logic[BLOCK_BITS - 1:0] batch_length_block, fetch_block_count, read_block_count; - logic[$clog2(`GFX_BATCH_FIFO_DEPTH + 1) - 1:0] fifo_pending; struct packed { @@ -46,14 +45,10 @@ module gfx_sp_batch assign out_data = fifo_out.data; assign out_mask = fifo_out.mask; - assign fifo_up = out_ready && out_valid; - assign fifo_down = lane_read && !lane_waitrequest; assign fifo_in.data = lane_readdata; assign {batch_length_block, batch_length_tail} = batch_length; - assign aligned_batch_base = batch_base[ - $bits(batch_base) - 1:$bits(batch_base) - $bits(vram_lane_addr) - ]; + assign aligned_batch_base = batch_base[`GFX_INSN_BITS_IN_LANE +: $bits(vram_lane_addr)]; gfx_sp_widener #(.WIDTH($bits(vram_lane_addr))) lane_bus ( @@ -79,6 +74,14 @@ module gfx_sp_batch .* ); + gfx_fifo_overflow #(.DEPTH(`GFX_BATCH_FIFO_DEPTH)) overflow + ( + .down(lane_read && !lane_waitrequest), + .empty(), + .down_safe(fifo_down_safe), + .* + ); + always_comb begin unique case (read_tail) 2'b00: fifo_in.mask = 4'b0000; @@ -95,29 +98,23 @@ module gfx_sp_batch if (!rst_n) begin state <= IDLE; lane_read <= 0; - fifo_pending <= 0; - end else begin - unique case (state) - IDLE: - if (batch_start) begin - state <= STREAM; - lane_read <= 1; - end - - STREAM: begin - if (!lane_read || !lane_waitrequest) - lane_read <= fifo_pending < `GFX_BATCH_FIFO_DEPTH - 1; - - if (lane_read && !lane_waitrequest && read_block_count == 0) - state <= IDLE; + end else unique case (state) + IDLE: + if (batch_start) begin + state <= STREAM; + lane_read <= 1; end - endcase - if (fifo_up && !fifo_down) - fifo_pending <= fifo_pending - 1; - else if (!fifo_up && fifo_down) - fifo_pending <= fifo_pending + 1; - end + STREAM: begin + if (!lane_read || !lane_waitrequest) + lane_read <= fifo_down_safe; + + if (lane_read && !lane_waitrequest && fetch_block_count == 0) begin + state <= IDLE; + lane_read <= 0; + end + end + endcase always_ff @(posedge clk) begin unique case (state) diff --git a/rtl/gfx/gfx_sp_fetch.sv b/rtl/gfx/gfx_sp_fetch.sv index 986862b..23fb20e 100644 --- a/rtl/gfx/gfx_sp_fetch.sv +++ b/rtl/gfx/gfx_sp_fetch.sv @@ -29,14 +29,13 @@ module gfx_sp_fetch localparam ENTRY_SIZE = 4; - logic break_loop, entry_end, fifo_down, fifo_up, fifo_put, header_continue, - insn_read, insn_readdatavalid, insn_waitrequest; + logic break_loop, entry_end, fifo_down_safe, fifo_empty, fifo_put, + header_continue, insn_read, insn_readdatavalid, insn_waitrequest; cmd_word header_count; insn_word code_length, code_read_ptr, code_fetch_ptr, insn_readdata, entry_data[ENTRY_SIZE]; vram_insn_addr code_base, insn_address, header_ptr; logic[$clog2(ENTRY_SIZE - 1):0] entry_fetch_count, entry_read_count; - logic[$clog2(`GFX_FETCH_FIFO_DEPTH + 1) - 1:0] fifo_pending; enum int unsigned { @@ -60,7 +59,7 @@ module gfx_sp_fetch assign break_loop = batch_end && (!insn_read || !insn_waitrequest); function vram_insn_addr base_from_word(insn_word in); - base_from_word = in[$bits(in) - 1:$bits(in) - $bits(vram_insn_addr)]; + base_from_word = in[`GFX_INSN_SUBWORD_BITS +: $bits(vram_insn_addr)]; endfunction assign code_base = base_from_word(entry_data[0]); @@ -68,9 +67,6 @@ module gfx_sp_fetch assign code_length = entry_data[1]; assign batch_length = entry_data[3]; - assign fifo_up = ready && valid; - assign fifo_down = insn_read && !insn_waitrequest; - gfx_sp_widener #(.WIDTH($bits(vram_insn_addr))) insn_bus ( .wide_read(insn_read), @@ -97,6 +93,16 @@ module gfx_sp_fetch .* ); + gfx_fifo_overflow #(.DEPTH(`GFX_FETCH_FIFO_DEPTH)) overflow + ( + .down(insn_read && !insn_waitrequest), + .empty(fifo_empty), + .down_safe(fifo_down_safe), + .out_ready(ready), + .out_valid(valid), + .* + ); + always_ff @(posedge clk or negedge rst_n) if (!rst_n) begin state <= IDLE; @@ -104,59 +110,51 @@ module gfx_sp_fetch fifo_put <= 0; insn_read <= 0; batch_start <= 0; - fifo_pending <= 0; - end else begin - unique case (state) - IDLE: - if (program_start) begin - state <= HEADER; - running <= 1; - insn_read <= 1; - end + end else unique case (state) + IDLE: + if (program_start) begin + state <= HEADER; + running <= 1; + insn_read <= 1; + end - HEADER: begin - if (insn_read && !insn_waitrequest) - insn_read <= entry_fetch_count == ENTRY_SIZE - 1; + HEADER: begin + if (insn_read && !insn_waitrequest) + insn_read <= entry_fetch_count != ENTRY_SIZE - 1; - if (insn_readdatavalid && entry_end) begin - state <= LOOP; - insn_read <= 1; - batch_start <= 1; - end + if (insn_readdatavalid && entry_end) begin + state <= LOOP; + insn_read <= 1; + batch_start <= 1; end + end - LOOP: begin - fifo_put <= 0; - batch_start <= 0; - - if (!insn_read || !insn_waitrequest) - insn_read <= fifo_pending < `GFX_FETCH_FIFO_DEPTH - 1; + LOOP: begin + fifo_put <= 0; + batch_start <= 0; - if (break_loop) begin - state <= FLUSH; - insn_read <= 0; - end + if (!insn_read || !insn_waitrequest) + insn_read <= fifo_down_safe; - if (insn_readdatavalid) - fifo_put <= 1; + if (break_loop) begin + state <= FLUSH; + insn_read <= 0; end - FLUSH: begin - fifo_put <= 0; + if (insn_readdatavalid) + fifo_put <= 1; + end - if (fifo_pending == 0) begin - state <= header_continue ? HEADER : IDLE; - running <= header_continue; - insn_read <= header_continue; - end - end - endcase + FLUSH: begin + fifo_put <= 0; - if (fifo_up && !fifo_down) - fifo_pending <= fifo_pending - 1; - else if (!fifo_up && fifo_down) - fifo_pending <= fifo_pending + 1; - end + if (fifo_empty) begin + state <= header_continue ? HEADER : IDLE; + running <= header_continue; + insn_read <= header_continue; + end + end + endcase always_ff @(posedge clk) unique case (state) @@ -217,7 +215,7 @@ module gfx_sp_fetch end FLUSH: - if (fifo_pending == 0) begin + if (fifo_empty) begin header_count <= header_count - 1; insn_address <= header_ptr; end -- cgit v1.2.3