From ca02833f22b08ceeeff501107371aa6667426115 Mon Sep 17 00:00:00 2001 From: Alejandro Soto Date: Sun, 5 May 2024 17:38:55 -0600 Subject: rtl/gfx: rename platform/wavelet3d -> rtl/gfx --- rtl/gfx/gfx_clz.sv | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 rtl/gfx/gfx_clz.sv (limited to 'rtl/gfx/gfx_clz.sv') diff --git a/rtl/gfx/gfx_clz.sv b/rtl/gfx/gfx_clz.sv new file mode 100644 index 0000000..8d6f100 --- /dev/null +++ b/rtl/gfx/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 -- cgit v1.2.3