diff options
| -rw-r--r-- | gfx_hw.tcl | 4 | ||||
| -rw-r--r-- | rtl/gfx/gfx_setup.sv | 190 | ||||
| -rw-r--r-- | rtl/gfx/gfx_setup_bounds.sv | 73 | ||||
| -rw-r--r-- | rtl/gfx/gfx_setup_edge.sv | 53 |
4 files changed, 319 insertions, 1 deletions
@@ -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 |
