summaryrefslogtreecommitdiff
path: root/rtl
diff options
context:
space:
mode:
Diffstat (limited to 'rtl')
-rw-r--r--rtl/gfx/gfx_defs.sv3
-rw-r--r--rtl/gfx/gfx_fixed_div.sv26
-rw-r--r--rtl/gfx/gfx_pipes.sv9
3 files changed, 30 insertions, 8 deletions
diff --git a/rtl/gfx/gfx_defs.sv b/rtl/gfx/gfx_defs.sv
index a9e711e..9ffa505 100644
--- a/rtl/gfx/gfx_defs.sv
+++ b/rtl/gfx/gfx_defs.sv
@@ -59,7 +59,8 @@ typedef struct packed
`define FIXED_FRAC 16
-`define FIXED_DIV_STAGES 8
+`define FIXED_DIV_PIPES 2
+`define FIXED_DIV_STAGES (`FIXED_DIV_PIPES + $bits(fixed) + `FIXED_FRAC)
`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
index 320d9b8..e562072 100644
--- a/rtl/gfx/gfx_fixed_div.sv
+++ b/rtl/gfx/gfx_fixed_div.sv
@@ -13,10 +13,11 @@ module gfx_fixed_div
localparam DIV_BITS = `FIXED_FRAC + $bits(fixed);
+ fixed d_hold, z_hold;
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}}};
+ assign z_int = {z_hold, {`FIXED_FRAC{1'b0}}};
`ifndef VERILATOR
lpm_divide div
@@ -25,7 +26,7 @@ module gfx_fixed_div
.clock(clk),
.clken(!stall),
.numer(z_int),
- .denom(d),
+ .denom(d_hold),
.remain(),
.quotient(q_int)
);
@@ -34,13 +35,28 @@ module gfx_fixed_div
div.lpm_widthn = DIV_BITS,
div.lpm_widthd = $bits(fixed),
div.lpm_nrepresentation = "SIGNED",
- div.lpm_nrepresentation = "SIGNED",
- div.lpm_pipeline = `FIXED_DIV_STAGES;
+ div.lpm_drepresentation = "SIGNED",
+ div.lpm_pipeline = `FIXED_DIV_STAGES - `FIXED_DIV_PIPES,
+ div.maximize_speed = 6;
+
+ gfx_pipes #(.WIDTH($bits(z)), .DEPTH(`FIXED_DIV_PIPES)) z_pipes
+ (
+ .in(z),
+ .out(z_hold),
+ .*
+ );
+
+ gfx_pipes #(.WIDTH($bits(d)), .DEPTH(`FIXED_DIV_PIPES)) d_pipes
+ (
+ .in(d),
+ .out(d_hold),
+ .*
+ );
`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 z_hold = z;
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
diff --git a/rtl/gfx/gfx_pipes.sv b/rtl/gfx/gfx_pipes.sv
index 09b1d43..390a481 100644
--- a/rtl/gfx/gfx_pipes.sv
+++ b/rtl/gfx/gfx_pipes.sv
@@ -17,8 +17,13 @@ module gfx_pipes
if (!stall) begin
pipes[0] <= in;
- for (integer i = 1; i < DEPTH; ++i)
- pipes[i] <= pipes[i - 1];
+ /* Esto tiene que ir así porque Verilator no soporta <= en for
+ * loops a las que no logre hacerle unrolling. Nótese que el
+ * orden de iteración descendiente es necesario porque estamos
+ * usando un blocking assignment dentro de always_ff.
+ */
+ for (integer i = DEPTH - 1; i > 0; --i)
+ pipes[i] = pipes[i - 1];
end
endmodule