summaryrefslogtreecommitdiff
path: root/rtl/gfx/gfx_perspective.sv
diff options
context:
space:
mode:
authorAlejandro Soto <alejandro@34project.org>2023-11-02 20:36:51 -0600
committerAlejandro Soto <alejandro@34project.org>2023-11-10 01:42:47 -0600
commit85fc7268a690e38ecb7f3b04dbfb8d70f2570a79 (patch)
tree5e7ba468b1c8e68c3835c59c83a10d285787ea37 /rtl/gfx/gfx_perspective.sv
parent814eb9d024a928380815a8a830eee3b86d71cf75 (diff)
rtl/gfx: implement perspective division
Diffstat (limited to 'rtl/gfx/gfx_perspective.sv')
-rw-r--r--rtl/gfx/gfx_perspective.sv69
1 files changed, 69 insertions, 0 deletions
diff --git a/rtl/gfx/gfx_perspective.sv b/rtl/gfx/gfx_perspective.sv
new file mode 100644
index 0000000..3cc38b2
--- /dev/null
+++ b/rtl/gfx/gfx_perspective.sv
@@ -0,0 +1,69 @@
+`include "gfx/gfx_defs.sv"
+
+module gfx_perspective
+(
+ input logic clk,
+
+ input attr4 clip_attr,
+ input logic stall,
+ in_start,
+ out_start,
+
+ output attr4 ndc_attr,
+ output fp w_inv
+);
+
+ fp selected_w_inv, next_w_inv, vertex_w_inv, w_inv_pipes[`FP_MUL_STAGES];
+ vec4 in_pipes[`FP_INV_STAGES], div_q;
+
+ assign w_inv = w_inv_pipes[`FP_MUL_STAGES - 1];
+ assign selected_w_inv = in_start ? next_w_inv : vertex_w_inv;
+
+ fp_inv inv
+ (
+ .a(clip_attr.w),
+ .q(next_w_inv),
+ .*
+ );
+
+ genvar i;
+ generate
+ for (i = 0; i < `FLOATS_PER_VEC; ++i) begin: divs
+ fp_mul div
+ (
+ .a(in_pipes[`FP_INV_STAGES - 1][i]),
+ .b(selected_w_inv),
+ .q(div_q[i]),
+ .*
+ );
+ end
+
+ for (i = 1; i < `FP_INV_STAGES; ++i) begin: in
+ always_ff @(posedge clk)
+ if (!stall)
+ in_pipes[i] <= in_pipes[i - 1];
+ end
+
+ for (i = 1; i < `FP_MUL_STAGES; ++i) begin: out
+ always_ff @(posedge clk)
+ if (!stall)
+ w_inv_pipes[i] <= w_inv_pipes[i - 1];
+ end
+ endgenerate
+
+ always_comb begin
+ ndc_attr = div_q;
+ if (out_start)
+ ndc_attr.w = `FP_UNIT;
+ end
+
+ always_ff @(posedge clk)
+ if (!stall) begin
+ if (in_start)
+ vertex_w_inv <= next_w_inv;
+
+ in_pipes[0] <= clip_attr;
+ w_inv_pipes[0] <= selected_w_inv;
+ end
+
+endmodule