summaryrefslogtreecommitdiff
path: root/rtl
diff options
context:
space:
mode:
authorAlejandro Soto <alejandro@34project.org>2023-11-19 20:54:04 -0600
committerAlejandro Soto <alejandro@34project.org>2023-11-20 21:29:11 -0600
commitce34e3dfb0fc38a5763f5b81360f35e6e880df91 (patch)
treefbe2d84e890cc7561604c17594d408d353f75857 /rtl
parent2d3c392de957db2252f935a4f2eb3f9a76943966 (diff)
rtl/gfx: factor FIFO overflow logic
Diffstat (limited to 'rtl')
-rw-r--r--rtl/gfx/gfx_fifo_overflow.sv34
-rw-r--r--rtl/gfx/gfx_sp_batch.sv53
-rw-r--r--rtl/gfx/gfx_sp_fetch.sv100
3 files changed, 108 insertions, 79 deletions
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