summaryrefslogtreecommitdiff
path: root/platform/wavelet3d/gfx_clz.sv
diff options
context:
space:
mode:
authorAlejandro Soto <alejandro@34project.org>2024-03-04 17:52:52 -0600
committerAlejandro Soto <alejandro@34project.org>2024-03-04 17:52:52 -0600
commitde9994dfb10d435725537a48fadde81fc38a6fc4 (patch)
treef6d4996253b96834ea6e2ad8c369adee00bd5ef5 /platform/wavelet3d/gfx_clz.sv
parent2b7b2185d381f2c5fd4aee19bd3a3508b4c9557f (diff)
platform/wavelet3d: implement fadd
Diffstat (limited to '')
-rw-r--r--platform/wavelet3d/gfx_clz.sv68
1 files changed, 68 insertions, 0 deletions
diff --git a/platform/wavelet3d/gfx_clz.sv b/platform/wavelet3d/gfx_clz.sv
new file mode 100644
index 0000000..8d6f100
--- /dev/null
+++ b/platform/wavelet3d/gfx_clz.sv
@@ -0,0 +1,68 @@
+/* Implementación en árbol de count leading zeros (CLZ).
+ * WIDTH debe ser una potencia de 2.
+ */
+module gfx_clz
+#(int WIDTH = 0)
+(
+ input logic clk,
+
+ input logic[WIDTH - 1:0] value,
+ output logic[$clog2(WIDTH):0] clz
+);
+
+ genvar i;
+ generate
+ if (WIDTH <= 1) begin
+ always_ff @(posedge clk)
+ clz <= !value;
+ end else if (WIDTH == 2) begin
+ always_ff @(posedge clk)
+ unique case (value)
+ 2'b00: clz <= 2'b10;
+ 2'b01: clz <= 2'b01;
+ 2'b10: clz <= 2'b00;
+ 2'b11: clz <= 2'b00;
+ endcase
+ end else if (WIDTH == 4) begin
+ // Eficiente en FPGAs con 4-LUTs
+ always_ff @(posedge clk)
+ if (value[3])
+ clz <= 3'b000;
+ else if (value[2])
+ clz <= 3'b001;
+ else if (value[1])
+ clz <= 3'b010;
+ else if (value[0])
+ clz <= 3'b011;
+ else
+ clz <= 3'b100;
+ end else begin
+ logic msb_right;
+ logic[$clog2(WIDTH) - 1:0] clz_left, clz_right;
+ logic[$clog2(WIDTH) - 2:0] tail_right;
+
+ assign {msb_right, tail_right} = clz_right;
+
+ gfx_clz #(WIDTH / 2) left
+ (
+ .clk(clk),
+ .clz(clz_left),
+ .value(value[WIDTH - 1:WIDTH / 2])
+ );
+
+ gfx_clz #(WIDTH / 2) right
+ (
+ .clk(clk),
+ .clz(clz_right),
+ .value(value[WIDTH / 2 - 1:0])
+ );
+
+ always_ff @(posedge clk)
+ if (clz_left[$clog2(WIDTH) - 1])
+ clz <= {msb_right, ~msb_right, tail_right};
+ else
+ clz <= {1'b0, clz_left};
+ end
+ endgenerate
+
+endmodule