summaryrefslogtreecommitdiff
path: root/rtl/gfx
diff options
context:
space:
mode:
Diffstat (limited to 'rtl/gfx')
-rw-r--r--rtl/gfx/gfx_defs.sv16
-rw-r--r--rtl/gfx/gfx_perspective.sv69
-rw-r--r--rtl/gfx/gfx_perspective_flow.sv50
-rw-r--r--rtl/gfx/pipeline_flow.sv2
4 files changed, 132 insertions, 5 deletions
diff --git a/rtl/gfx/gfx_defs.sv b/rtl/gfx/gfx_defs.sv
index 1fe0df2..6e96b4e 100644
--- a/rtl/gfx/gfx_defs.sv
+++ b/rtl/gfx/gfx_defs.sv
@@ -11,10 +11,18 @@
`define FP_MUL_STAGES 5 // ~144 LUTs ~1 bloque DSP
`define FP_INV_STAGES 3 // ~178 LUTs ~1 bloque DSP
-typedef logic[`FLOAT_BITS - 1:0] fp;
-typedef fp vec2[2];
-typedef fp vec4[`FLOATS_PER_VEC];
-typedef vec4 mat4[`VECS_PER_MAT];
+typedef logic[`FLOAT_BITS - 1:0] fp;
+typedef fp vec2[2];
+typedef fp vec4[`FLOATS_PER_VEC];
+typedef fp[`FLOATS_PER_VEC - 1:0] vec4_packed;
+typedef vec4 mat4[`VECS_PER_MAT];
+
+`define FP_UNIT 16'h3c00
+
+typedef struct packed
+{
+ fp x, y, z, w;
+} attr4;
typedef logic[1:0] index4;
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
diff --git a/rtl/gfx/gfx_perspective_flow.sv b/rtl/gfx/gfx_perspective_flow.sv
new file mode 100644
index 0000000..ecacc65
--- /dev/null
+++ b/rtl/gfx/gfx_perspective_flow.sv
@@ -0,0 +1,50 @@
+`include "gfx/gfx_defs.sv"
+
+module gfx_perspective_flow
+(
+ input logic clk,
+ rst_n,
+
+ input logic vertex_start,
+ output logic stall,
+ in_start,
+ out_start,
+
+ input logic in_valid,
+ out_ready,
+
+ output logic in_ready,
+ out_valid
+ stall
+);
+
+ localparam STAGES = `FP_INV_STAGES + `FP_MUL_STAGES;
+
+ logic[STAGES - 1:0] start_pipes;
+
+ assign in_start = start_pipes[`FP_INV_STAGES - 1];
+ assign out_start = start_pipes[STAGES - 1];
+
+ pipeline_flow #(.STAGES(STAGES)) flow
+ (
+ .*
+ );
+
+ always_ff @(posedge clk or negedge rst_n)
+ if (!rst_n)
+ start_pipes[0] <= 0;
+ else if (!stall)
+ start_pipes[0] <= in_valid && vertex_start;
+
+ genvar i;
+ generate
+ for (i = 1; i < STAGES; ++i) begin: pipeline
+ always_ff @(posedge clk or negedge rst_n)
+ if (!rst_n)
+ start_pipes[i] <= 0;
+ else if (!stall)
+ start_pipes[i] <= start_pipes[i - 1];
+ end
+ endgenerate
+
+endmodule
diff --git a/rtl/gfx/pipeline_flow.sv b/rtl/gfx/pipeline_flow.sv
index 15986d0..64b5714 100644
--- a/rtl/gfx/pipeline_flow.sv
+++ b/rtl/gfx/pipeline_flow.sv
@@ -12,7 +12,7 @@ module pipeline_flow
stall
);
- logic valid[STAGES];
+ logic[STAGES - 1:0] valid;
skid_flow skid
(