stack-machine/nlz.v

51 lines
1.4 KiB
Verilog

// Computes the number of leading zeros in the input. Result is 0...32.
module NLZ (IN, OUT);
input [31:0] IN;
output [5:0] OUT;
wire [7:0] PARTS = {
|IN[31:28], |IN[27:24], |IN[23:20], |IN[19:16],
|IN[15:12], |IN[11: 8], |IN[ 7: 4], |IN[ 3: 0]
};
// synthesis attribute priority_extract of LEADING_PARTS is force;
reg [2:0] LEADING_PARTS;
reg [1:0] LEADING_BITS;
reg [3:0] PART;
always @*
begin
if (PARTS[7]) LEADING_PARTS <= 3'b000;
else if (PARTS[6]) LEADING_PARTS <= 3'b001;
else if (PARTS[5]) LEADING_PARTS <= 3'b010;
else if (PARTS[4]) LEADING_PARTS <= 3'b011;
else if (PARTS[3]) LEADING_PARTS <= 3'b100;
else if (PARTS[2]) LEADING_PARTS <= 3'b101;
else if (PARTS[1]) LEADING_PARTS <= 3'b110;
else if (PARTS[0]) LEADING_PARTS <= 3'b111;
else LEADING_PARTS <= 3'bXXX;
case (LEADING_PARTS)
3'b000: PART <= IN[31:28];
3'b001: PART <= IN[27:24];
3'b010: PART <= IN[23:20];
3'b011: PART <= IN[19:16];
3'b100: PART <= IN[15:12];
3'b101: PART <= IN[11: 8];
3'b110: PART <= IN[ 7: 4];
3'b111: PART <= IN[ 3: 0];
endcase
casex (PART)
4'b1XXX: LEADING_BITS <= 2'b00;
4'b01XX: LEADING_BITS <= 2'b01;
4'b001X: LEADING_BITS <= 2'b10;
4'b000X: LEADING_BITS <= 2'b11;
endcase
end
assign OUT = (~|PARTS) ? 6'd32 : { LEADING_PARTS, LEADING_BITS };
endmodule