OpenCores
URL https://opencores.org/ocsvn/fast_log/fast_log/trunk

Subversion Repositories fast_log

[/] [fast_log/] [trunk/] [Log2highacc.v] - Rev 6

Compare with Previous | Blame | View Log

module Log2highacc
 
/* 
A fast base-2 logarithm function, 24 bits (22 used) in, 12 bits out.
Designed and coded by: Michael Dunn, http://www.cantares.on.ca/
(more info at the web site - see "Extras")
Executes every cycle, with a latency of 3.
 
Compared to previous versions, this one has a larger, higher resolution
lookup table. This provides a smoother and more accurate output, though
a downside of having higher LUT resolution than the LUT depth fully
supports is that there are missing codes in the output. If this is a problem,
the lower 2 or 3 output bits can be ignored. In most cases, use all the
bits you can!
 
Valid input range = 000100 - FFFFFF. In effect, there is a binary point:
xxxx.yy. Logs of inputs below 1.00 are negative, and not handled by this design.
 
License: Free to use & modify, but please keep this header intact.
August 2, 2010, Kitchener, Ontario, Canada
*/
 
(
	input [23:0]	DIN,
	input			clk,
 
	output	[11:0]	DOUT
);
 
 
// Comprises 4 main blocks: priority encoder, barrel shifter, LUT, and adder.
 
reg	[3:0]	priencout1;
reg	[3:0]	priencout2;
reg	[3:0]	priencout3;
reg	[5:0]	barrelout;
reg	[20:0]	barrelin;
reg	[7:0]	LUTout;
 
assign	DOUT	=	{priencout3, LUTout};	// Basic top-level connectivity
 
always @(posedge clk) 					
begin
	priencout2	<=	priencout1;
	priencout3	<=	priencout2;
	barrelin	<=	DIN[22:2];
end
 
 
wire [20:0] tmp1 =	(barrelin << ~priencout1);	// Barrel shifter - OMG, it's a primitive in Verilog!
always @(posedge clk)
begin
	barrelout	<=	tmp1[20:15];
end
 
 
wire	[15:0]	priencin = DIN[23:8];
 
always @(posedge clk)						// Priority encoder
 
casex (priencin)
 
	16'b1xxxxxxxxxxxxxxx:	priencout1	<=	15;
	16'b01xxxxxxxxxxxxxx:	priencout1	<=	14;
	16'b001xxxxxxxxxxxxx:	priencout1	<=	13;	
	16'b0001xxxxxxxxxxxx:	priencout1	<=	12;	
	16'b00001xxxxxxxxxxx:	priencout1	<=	11;	
	16'b000001xxxxxxxxxx:	priencout1	<=	10;	
	16'b0000001xxxxxxxxx:	priencout1	<=	9;	
	16'b00000001xxxxxxxx:	priencout1	<=	8;	
	16'b000000001xxxxxxx:	priencout1	<=	7;	
	16'b0000000001xxxxxx:	priencout1	<=	6;	
	16'b00000000001xxxxx:	priencout1	<=	5;	
	16'b000000000001xxxx:	priencout1	<=	4;	
	16'b0000000000001xxx:	priencout1	<=	3;	
	16'b00000000000001xx:	priencout1	<=	2;	
	16'b000000000000001x:	priencout1	<=	1;	
	16'b000000000000000x:	priencout1	<=	0;
 
endcase
 
 
 
/*
LUT for log fraction lookup
 - can be done with array or case:
 
case (addr)
0:out=0;
.
31:out=15;
endcase
 
	OR
 
wire [3:0] lut [0:31];
assign lut[0] = 0;
.
assign lut[31] = 15;
 
Are there any better ways?
*/
 
// Let's try "case".
// The equation is: output = log2(1+input/64)*256
// For larger tables, better to generate a separate data file using a program!
 
always @(posedge clk)
case (barrelout)
 
	0:	LUTout	<=	0;
	1:	LUTout	<=	6;
	2:	LUTout	<=	11;
	3:	LUTout	<=	17;
	4:	LUTout	<=	22;
	5:	LUTout	<=	28;
	6:	LUTout	<=	33;
	7:	LUTout	<=	38;
	8:	LUTout	<=	44;
	9:	LUTout	<=	49;
	10:	LUTout	<=	54;
	11:	LUTout	<=	59;
	12:	LUTout	<=	63;
	13:	LUTout	<=	68;
	14:	LUTout	<=	73;
	15:	LUTout	<=	78;
	16:	LUTout	<=	82;
	17:	LUTout	<=	87;
	18:	LUTout	<=	92;
	19:	LUTout	<=	96;
	20:	LUTout	<=	100;
	21:	LUTout	<=	105;
	22:	LUTout	<=	109;
	23:	LUTout	<=	113;
	24:	LUTout	<=	118;
	25:	LUTout	<=	122;
	26:	LUTout	<=	126;
	27:	LUTout	<=	130;
	28:	LUTout	<=	134;
	29:	LUTout	<=	138;
	30:	LUTout	<=	142;
	31:	LUTout	<=	146;
	32:	LUTout	<=	150;
	33:	LUTout	<=	154;
	34:	LUTout	<=	157;
	35:	LUTout	<=	161;
	36:	LUTout	<=	165;
	37:	LUTout	<=	169;
	38:	LUTout	<=	172;
	39:	LUTout	<=	176;
	40:	LUTout	<=	179;
	41:	LUTout	<=	183;
	42:	LUTout	<=	186;
	43:	LUTout	<=	190;
	44:	LUTout	<=	193;
	45:	LUTout	<=	197;
	46:	LUTout	<=	200;
	47:	LUTout	<=	203;
	48:	LUTout	<=	207;
	49:	LUTout	<=	210;
	50:	LUTout	<=	213;
	51:	LUTout	<=	216;
	52:	LUTout	<=	220;
	53:	LUTout	<=	223;
	54:	LUTout	<=	226;
	55:	LUTout	<=	229;
	56:	LUTout	<=	232;
	57:	LUTout	<=	235;
	58:	LUTout	<=	238;
	59:	LUTout	<=	241;
	60:	LUTout	<=	244;
	61:	LUTout	<=	247;
	62:	LUTout	<=	250;
	63:	LUTout	<=	253;
 
endcase
 
endmodule
 

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.