summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gfx_hw.tcl4
-rw-r--r--rtl/gfx/gfx_setup.sv190
-rw-r--r--rtl/gfx/gfx_setup_bounds.sv73
-rw-r--r--rtl/gfx/gfx_setup_edge.sv53
4 files changed, 319 insertions, 1 deletions
diff --git a/gfx_hw.tcl b/gfx_hw.tcl
index 2162528..46aabce 100644
--- a/gfx_hw.tcl
+++ b/gfx_hw.tcl
@@ -60,8 +60,10 @@ add_fileset_file gfx_transpose.sv SYSTEM_VERILOG PATH rtl/gfx/gfx_transpose.sv
add_fileset_file gfx_scanout.sv SYSTEM_VERILOG PATH rtl/gfx/gfx_scanout.sv
add_fileset_file gfx_masks.sv SYSTEM_VERILOG PATH rtl/gfx/gfx_masks.sv
add_fileset_file gfx_mask_sram.sv SYSTEM_VERILOG PATH rtl/gfx/gfx_mask_sram.sv
+add_fileset_file gfx_setup.sv SYSTEM_VERILOG PATH rtl/gfx/gfx_setup.sv
+add_fileset_file gfx_setup_edge.sv SYSTEM_VERILOG PATH rtl/gfx/gfx_setup_edge.sv
+add_fileset_file gfx_setup_bounds.sv SYSTEM_VERILOG PATH rtl/gfx/gfx_setup_bounds.sv
add_fileset_file gfx_setup_offsets.sv SYSTEM_VERILOG PATH rtl/gfx/gfx_setup_offsets.sv
-add_fileset_file gfx_fine.sv SYSTEM_VERILOG PATH rtl/gfx/gfx_fine.sv
#
diff --git a/rtl/gfx/gfx_setup.sv b/rtl/gfx/gfx_setup.sv
new file mode 100644
index 0000000..1213645
--- /dev/null
+++ b/rtl/gfx/gfx_setup.sv
@@ -0,0 +1,190 @@
+`include "gfx/gfx_defs.sv"
+
+module gfx_setup
+(
+ input logic clk,
+
+ input raster_xy vertex_a,
+ vertex_b,
+ vertex_c,
+ input logic stall,
+
+ output raster_xy pos_ref,
+ output coarse_dim span_x,
+ span_y,
+ output raster_offsets_tri offsets,
+ output fixed_tri edge_refs,
+ coarse_x_offsets,
+ coarse_y_offsets,
+ coarse_test_offsets
+);
+
+ // FIXME FIXME FIXME: Top-left rule
+
+ fixed_tri edge_base, edge_inc_x, edge_inc_y, out_edge_refs, x_offsets, y_offsets, test_offsets;
+
+ raster_xy bounds_ref, hold_vertex_a, hold_vertex_b, hold_vertex_c, ps[3], qs[3], out_pos_ref;
+ coarse_dim bounds_span_x, bounds_span_y, out_span_x, out_span_y;
+ raster_offsets_tri out_offsets;
+
+ struct packed
+ {
+ raster_xy pos_ref;
+ coarse_dim span_x,
+ span_y;
+ raster_offsets_tri offsets;
+ fixed_tri edge_refs,
+ coarse_x_offsets,
+ coarse_y_offsets,
+ coarse_test_offsets;
+ } out, skid_out;
+
+ gfx_skid_buf #(.WIDTH($bits(out))) skid
+ (
+ .in(out),
+ .out(skid_out),
+ .*
+ );
+
+ assign out.span_x = out_span_x;
+ assign out.span_y = out_span_y;
+ assign out.pos_ref = out_pos_ref;
+ assign out.offsets = out_offsets;
+ assign out.edge_refs = out_edge_refs;
+ assign out.coarse_x_offsets = x_offsets;
+ assign out.coarse_y_offsets = y_offsets;
+ assign out.coarse_test_offsets = test_offsets;
+
+ assign span_x = skid_out.span_x;
+ assign span_y = skid_out.span_y;
+ assign pos_ref = skid_out.pos_ref;
+ assign offsets = skid_out.offsets;
+ assign edge_refs = skid_out.edge_refs;
+ assign coarse_x_offsets = skid_out.coarse_x_offsets;
+ assign coarse_y_offsets = skid_out.coarse_y_offsets;
+ assign coarse_test_offsets = skid_out.coarse_test_offsets;
+
+ assign ps[0] = hold_vertex_a;
+ assign qs[0] = hold_vertex_b;
+
+ assign ps[1] = hold_vertex_b;
+ assign qs[1] = hold_vertex_c;
+
+ assign ps[2] = hold_vertex_c;
+ assign qs[2] = hold_vertex_a;
+
+ gfx_pipes #(.WIDTH($bits(vertex_a)), .DEPTH(`GFX_SETUP_BOUNDS_STAGES)) vertex_a_pipes
+ (
+ .in(vertex_a),
+ .out(hold_vertex_a),
+ .*
+ );
+
+ gfx_pipes #(.WIDTH($bits(vertex_b)), .DEPTH(`GFX_SETUP_BOUNDS_STAGES)) vertex_b_pipes
+ (
+ .in(vertex_b),
+ .out(hold_vertex_b),
+ .*
+ );
+
+ gfx_pipes #(.WIDTH($bits(vertex_c)), .DEPTH(`GFX_SETUP_BOUNDS_STAGES)) vertex_c_pipes
+ (
+ .in(vertex_c),
+ .out(hold_vertex_c),
+ .*
+ );
+
+ gfx_setup_bounds bounds
+ (
+ .span_x(bounds_span_x),
+ .span_y(bounds_span_y),
+ .reference(bounds_ref),
+ .*
+ );
+
+ localparam POST_BOUNDS_DEPTH = `GFX_SETUP_EDGE_STAGES + `GFX_SETUP_OFFSETS_STAGES;
+
+ gfx_pipes #(.WIDTH($bits(pos_ref)), .DEPTH(POST_BOUNDS_DEPTH)) ref_pipes
+ (
+ .in(bounds_ref),
+ .out(out_pos_ref),
+ .*
+ );
+
+ gfx_pipes #(.WIDTH($bits(span_x)), .DEPTH(POST_BOUNDS_DEPTH)) span_x_pipes
+ (
+ .in(bounds_span_x),
+ .out(out_span_x),
+ .*
+ );
+
+ gfx_pipes #(.WIDTH($bits(span_y)), .DEPTH(POST_BOUNDS_DEPTH)) span_y_pipes
+ (
+ .in(bounds_span_y),
+ .out(out_span_y),
+ .*
+ );
+
+ always_comb
+ for (integer i = 0; i < 3; ++i)
+ // Imaginárselo
+ unique case ({x_offsets[i][$bits(fixed) - 1], y_offsets[i][$bits(fixed) - 1]})
+ 2'b00:
+ test_offsets[i] = out_offsets[i][`GFX_RASTER_OFFSETS - 1];
+
+ 2'b01:
+ test_offsets[i] = out_offsets[i][`GFX_RASTER_SIZE - 1];
+
+ 2'b10:
+ test_offsets[i] = out_offsets[i][`GFX_RASTER_OFFSETS - `GFX_RASTER_SIZE - 1];
+
+ 2'b11:
+ test_offsets[i] = out_offsets[i][0];
+ endcase
+
+ genvar i;
+ generate
+ for (i = 0; i < 3; ++i) begin: edges
+ gfx_setup_edge edge_fn
+ (
+ .p(ps[i]),
+ .q(qs[i]),
+ .base(edge_base[i]),
+ .inc_x(edge_inc_x[i]),
+ .inc_y(edge_inc_y[i]),
+ .origin(bounds_ref),
+ .*
+ );
+
+ gfx_pipes #(.WIDTH($bits(fixed)), .DEPTH(`GFX_SETUP_OFFSETS_STAGES)) base_pipes
+ (
+ .in(edge_base[i]),
+ .out(out_edge_refs[i]),
+ .*
+ );
+
+ gfx_pipes #(.WIDTH($bits(fixed)), .DEPTH(`GFX_SETUP_OFFSETS_STAGES)) coarse_x_pipes
+ (
+ .in(edge_inc_x[i] << `GFX_RASTER_BITS),
+ .out(x_offsets[i]),
+ .*
+ );
+
+ gfx_pipes #(.WIDTH($bits(fixed)), .DEPTH(`GFX_SETUP_OFFSETS_STAGES)) coarse_y_pipes
+ (
+ .in(edge_inc_y[i] << `GFX_RASTER_BITS),
+ .out(y_offsets[i]),
+ .*
+ );
+
+ gfx_setup_offsets edge_offsets
+ (
+ .inc_x(edge_inc_x[i]),
+ .inc_y(edge_inc_y[i]),
+ .offsets(out_offsets[i]),
+ .*
+ );
+ end
+ endgenerate
+
+endmodule
diff --git a/rtl/gfx/gfx_setup_bounds.sv b/rtl/gfx/gfx_setup_bounds.sv
new file mode 100644
index 0000000..6a93db2
--- /dev/null
+++ b/rtl/gfx/gfx_setup_bounds.sv
@@ -0,0 +1,73 @@
+`include "gfx/gfx_defs.sv"
+
+module gfx_setup_bounds
+(
+ input logic clk,
+
+ input raster_xy vertex_a,
+ vertex_b,
+ vertex_c,
+ input logic stall,
+
+ output raster_xy reference,
+ output coarse_dim span_x,
+ span_y
+);
+
+ logic x_a_lt_b, x_a_lt_c, x_b_lt_c, y_a_lt_b, y_a_lt_c, y_b_lt_c;
+ raster_xy min, max, hold_a, hold_b, hold_c;
+ coarse_dim ref_x, ref_y;
+ raster_xy_prec min_prec, max_prec, ref_prec;
+
+ assign min_prec = min;
+ assign max_prec = max;
+ assign reference = ref_prec;
+
+ assign ref_prec.x.sub = 0;
+ assign ref_prec.x.fine = 0;
+ assign ref_prec.x.coarse = ref_x;
+ assign ref_prec.x.padding = 0;
+
+ assign ref_prec.y.sub = 0;
+ assign ref_prec.y.fine = 0;
+ assign ref_prec.y.coarse = ref_y;
+ assign ref_prec.y.padding = 0;
+
+ always_ff @(posedge clk)
+ if (!stall) begin
+ hold_a <= vertex_a;
+ hold_b <= vertex_b;
+ hold_c <= vertex_c;
+
+ x_a_lt_b <= vertex_a.x < vertex_b.x;
+ x_a_lt_c <= vertex_a.x < vertex_c.x;
+ x_b_lt_c <= vertex_b.x < vertex_c.x;
+
+ y_a_lt_b <= vertex_a.y < vertex_b.y;
+ y_a_lt_c <= vertex_a.y < vertex_c.y;
+ y_b_lt_c <= vertex_b.y < vertex_c.y;
+
+ if (x_a_lt_b) begin
+ min.x <= x_a_lt_c ? hold_a.x : hold_c.x;
+ max.x <= x_b_lt_c ? hold_c.x : hold_b.x;
+ end else begin
+ min.x <= x_b_lt_c ? hold_b.x : hold_c.x;
+ max.x <= x_a_lt_c ? hold_c.x : hold_a.x;
+ end
+
+ if (y_a_lt_b) begin
+ min.y <= y_a_lt_c ? hold_a.y : hold_c.y;
+ max.y <= y_b_lt_c ? hold_c.y : hold_b.y;
+ end else begin
+ min.y <= y_b_lt_c ? hold_b.y : hold_c.y;
+ max.y <= y_a_lt_c ? hold_c.y : hold_a.y;
+ end
+
+ ref_x <= min_prec.x.coarse;
+ ref_y <= min_prec.y.coarse;
+
+ span_x <= max_prec.x.coarse - min_prec.x.coarse;
+ span_y <= max_prec.y.coarse - min_prec.y.coarse;
+ end
+
+endmodule
diff --git a/rtl/gfx/gfx_setup_edge.sv b/rtl/gfx/gfx_setup_edge.sv
new file mode 100644
index 0000000..5d69a88
--- /dev/null
+++ b/rtl/gfx/gfx_setup_edge.sv
@@ -0,0 +1,53 @@
+`include "gfx/gfx_defs.sv"
+
+module gfx_setup_edge
+(
+ input logic clk,
+
+ input raster_xy p,
+ q,
+ origin,
+ input logic stall,
+
+ output fixed base,
+ inc_x,
+ inc_y
+);
+
+ fixed delta_x, delta_y, hold_inc_x, hold_inc_y;
+
+ gfx_pipes #(.WIDTH($bits(inc_x)), .DEPTH(`FIXED_FMA_DOT_STAGES)) inc_x_pipes
+ (
+ .in(hold_inc_x),
+ .out(inc_x),
+ .*
+ );
+
+ gfx_pipes #(.WIDTH($bits(inc_y)), .DEPTH(`FIXED_FMA_DOT_STAGES)) inc_y_pipes
+ (
+ .in(hold_inc_y),
+ .out(inc_y),
+ .*
+ );
+
+ gfx_fixed_fma_dot edge_base
+ (
+ .c(0),
+ .q(base),
+ .a0(delta_x),
+ .b0(hold_inc_x),
+ .a1(delta_y),
+ .b1(hold_inc_y),
+ .*
+ );
+
+ always_ff @(posedge clk)
+ if (!stall) begin
+ delta_x <= origin.x - q.x;
+ delta_y <= origin.y - q.y;
+
+ hold_inc_x <= p.y - q.y;
+ hold_inc_y <= q.x - p.x;
+ end
+
+endmodule