summaryrefslogtreecommitdiff
path: root/rtl/gfx
diff options
context:
space:
mode:
authorAlejandro Soto <alejandro@34project.org>2023-11-12 20:38:12 -0600
committerAlejandro Soto <alejandro@34project.org>2023-11-14 07:48:52 -0600
commita401d413ba766b01aa980a8e013c79500a490c2e (patch)
treef63e74634a1b0b15cc449c88f190ff7a6b8f25a0 /rtl/gfx
parentbf6b4e2e8ebb63f6b8466bc98650ce75f3bdc79f (diff)
rtl/gfx: implement fixed-point division
Diffstat (limited to 'rtl/gfx')
-rw-r--r--rtl/gfx/gfx_defs.sv1
-rw-r--r--rtl/gfx/gfx_fixed_div.sv61
2 files changed, 62 insertions, 0 deletions
diff --git a/rtl/gfx/gfx_defs.sv b/rtl/gfx/gfx_defs.sv
index 429928c..bffbb1f 100644
--- a/rtl/gfx/gfx_defs.sv
+++ b/rtl/gfx/gfx_defs.sv
@@ -59,6 +59,7 @@ typedef struct packed
`define FIXED_FRAC 16
+`define FIXED_DIV_STAGES 8
`define FIXED_FMA_STAGES 5
`define FIXED_FMA_DOT_STAGES (2 * `FIXED_FMA_STAGES)
`define LERP_STAGES `FIXED_FMA_DOT_STAGES
diff --git a/rtl/gfx/gfx_fixed_div.sv b/rtl/gfx/gfx_fixed_div.sv
new file mode 100644
index 0000000..320d9b8
--- /dev/null
+++ b/rtl/gfx/gfx_fixed_div.sv
@@ -0,0 +1,61 @@
+`include "gfx/gfx_defs.sv"
+
+module gfx_fixed_div
+(
+ input logic clk,
+
+ input fixed z,
+ d,
+ input logic stall,
+
+ output fixed q
+);
+
+ localparam DIV_BITS = `FIXED_FRAC + $bits(fixed);
+
+ logic signed[DIV_BITS - 1:0] z_int, q_int;
+
+ assign q = q_int[$bits(q) - 1:0];
+ assign z_int = {z, {`FIXED_FRAC{1'b0}}};
+
+`ifndef VERILATOR
+ lpm_divide div
+ (
+ .aclr(0),
+ .clock(clk),
+ .clken(!stall),
+ .numer(z_int),
+ .denom(d),
+ .remain(),
+ .quotient(q_int)
+ );
+
+ defparam
+ div.lpm_widthn = DIV_BITS,
+ div.lpm_widthd = $bits(fixed),
+ div.lpm_nrepresentation = "SIGNED",
+ div.lpm_nrepresentation = "SIGNED",
+ div.lpm_pipeline = `FIXED_DIV_STAGES;
+`else
+ fixed d_hold;
+ logic signed[DIV_BITS - 1:0] d_int_hold, z_int_hold;
+
+ assign q_int = z_int_hold / d_int_hold;
+ assign d_int_hold = {{`FIXED_FRAC{d_hold[$bits(d_hold) - 1]}}, d_hold};
+
+ gfx_pipes #(.WIDTH($bits(z_int)), .DEPTH(`FIXED_DIV_STAGES)) z_int_pipes
+ (
+ .in(z_int),
+ .out(z_int_hold),
+ .*
+ );
+
+ gfx_pipes #(.WIDTH($bits(d)), .DEPTH(`FIXED_DIV_STAGES)) d_pipes
+ (
+ .in(d),
+ .out(d_hold),
+ .*
+ );
+`endif
+
+endmodule