Wednesday, November 19, 2014

[verilog] fixed point log


This algorithm based on here -> http://www.quinapalus.com/efunc.html
I coded this algorithm using a verilogHDL and I designed a combinational logic. so you can change the design using a sequential logic and pipeline architecture.

This is 32bit fixed point logarithme for verilogHDL.

/*
 * k log(k)
 * 32760 10.3969
 * 256 5.5452
 * 16 2.7726
 * 4 1.3863
 * 2 0.6931
 * 3/2 0.4055
 * 5/4 0.2231
 * 9/8 0.1178
 * 17/16 0.0606
 * 33/32 0.0308
 * 65/64 0.0155
 * 129/128 0.0078
 *
 * 32bit
 * fix point
 * 16bit.16bit
 * */

module fxlog(
                x,

                y
               );

input [31:0] x;
output [31:0] y;

wire [31:0] tmp0,tmp1,tmp2,tmp3,tmp4,tmp5,tmp6;
wire [31:0] tmp_x0,tmp_x1,tmp_x2,tmp_x3,tmp_x4,
tmp_x5,tmp_x6,tmp_x7,tmp_x8,tmp_x9,
tmp_x10,tmp_x11,tmp_x12;
wire [31:0] tmp_y0,tmp_y1,tmp_y2,tmp_y3,tmp_y4,
tmp_y5,tmp_y6,tmp_y7,tmp_y8,tmp_y9,
tmp_y10,tmp_y11,tmp_y12;

assign tmp_x0  = (x < 32'h00008000) ? (x<<16) : x;
assign tmp_x1  = (tmp_x0 < 32'h00800000) ? (tmp_x0<< 8) : tmp_x0;
assign tmp_x2  = (tmp_x1 < 32'h08000000) ? (tmp_x1<< 4) : tmp_x1;
assign tmp_x3  = (tmp_x2 < 32'h20000000) ? (tmp_x2<< 2) : tmp_x2;
assign tmp_x4  = (tmp_x3 < 32'h40000000) ? (tmp_x3<< 1) : tmp_x3;
assign tmp_x5  = ((tmp0&32'h80000000) == 0) ? tmp0 : tmp_x4;
assign tmp_x6  = ((tmp1&32'h80000000) == 0) ? tmp1 : tmp_x5;
assign tmp_x7  = ((tmp2&32'h80000000) == 0) ? tmp2 : tmp_x6;
assign tmp_x8  = ((tmp3&32'h80000000) == 0) ? tmp3 : tmp_x7;
assign tmp_x9  = ((tmp4&32'h80000000) == 0) ? tmp4 : tmp_x8;
assign tmp_x10 = ((tmp5&32'h80000000) == 0) ? tmp5 : tmp_x9;
assign tmp_x11 = ((tmp6&32'h80000000) == 0) ? tmp6 : tmp_x10;

assign tmp0 = tmp_x4  + (tmp_x4 >>1);
assign tmp1 = tmp_x5  + (tmp_x5 >>2);
assign tmp2 = tmp_x6  + (tmp_x6 >>3);
assign tmp3 = tmp_x7  + (tmp_x7 >>4);
assign tmp4 = tmp_x8  + (tmp_x8 >>5);
assign tmp5 = tmp_x9  + (tmp_x9 >>6);
assign tmp6 = tmp_x10 + (tmp_x10>>7);

assign tmp_y0  = 32'ha65af;
assign tmp_y1  = (x < 32'h00008000) ? tmp_y0  - 32'hb1721 : tmp_y0;
assign tmp_y2  = (tmp_x0 < 32'h00800000) ? tmp_y1  - 32'h58b91 : tmp_y1;
assign tmp_y3  = (tmp_x1 < 32'h08000000) ? tmp_y2  - 32'h2c5c8 : tmp_y2;
assign tmp_y4  = (tmp_x2 < 32'h20000000) ? tmp_y3  - 32'h162e4 : tmp_y3;
assign tmp_y5  = (tmp_x3 < 32'h40000000) ? tmp_y4  - 32'h0b172 : tmp_y4;
assign tmp_y6  = ((tmp0&32'h80000000) == 0) ? tmp_y5  - 32'h067cd : tmp_y5;
assign tmp_y7  = ((tmp1&32'h80000000) == 0) ? tmp_y6  - 32'h03920 : tmp_y6;
assign tmp_y8  = ((tmp2&32'h80000000) == 0) ? tmp_y7  - 32'h01e27 : tmp_y7;
assign tmp_y9  = ((tmp3&32'h80000000) == 0) ? tmp_y8  - 32'h00f85 : tmp_y8;
assign tmp_y10 = ((tmp4&32'h80000000) == 0) ? tmp_y9  - 32'h007e1 : tmp_y9;
assign tmp_y11 = ((tmp5&32'h80000000) == 0) ? tmp_y10 - 32'h003f8 : tmp_y10;
assign tmp_y12 = ((tmp6&32'h80000000) == 0) ? tmp_y11 - 32'h001fe : tmp_y11;
 
assign tmp_x12 = 32'h80000000 - tmp_x11;
assign y = tmp_y12 - (tmp_x12>>15);

endmodule

No comments :

Post a Comment