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

Subversion Repositories fast_log

[/] [fast_log/] [trunk/] [Log2pipelined.v] - Blame information for rev 4

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 MichaelDun
module Log2pipelined
2
 
3
/*
4 4 MichaelDun
A fast base-2 logarithm function, 24 bits (21 used) in, 8 bits out.
5 2 MichaelDun
Designed and coded by: Michael Dunn, http://www.cantares.on.ca/
6
(more info at the web site - see "Extras")
7
Executes every cycle, with a latency of 3.
8 4 MichaelDun
 
9
This version has a smallish lookup table, hence, a slightly uneven output.
10
Valid input range = 000100 - FFFFFF. In effect, there is a binary point:
11
xxxx.yy. Logs of inputs below 1.00 are negative, and not handled by this design.
12
 
13 2 MichaelDun
License: Free to use & modify, but please keep this header intact.
14 4 MichaelDun
July 22, 2010, Kitchener, Ontario, Canada
15 2 MichaelDun
*/
16
 
17
(
18
        input [23:0]     DIN,
19
        input                   clk,
20
 
21
        output  [7:0]    DOUT
22
);
23
 
24
 
25
// Comprises 3 main blocks: priority encoder, barrel shifter, and LUT
26
 
27
reg     [3:0]    priencout1;
28
reg     [3:0]    priencout2;
29
reg     [3:0]    priencout3;
30
reg     [4:0]    barrelout;
31 4 MichaelDun
reg     [19:0]   barrelin;
32 2 MichaelDun
reg     [3:0]    LUTout;
33
 
34
 
35 4 MichaelDun
assign  DOUT    =       {priencout3, LUTout};   // Basic top-level connectivity
36 2 MichaelDun
 
37 4 MichaelDun
always @(posedge clk)
38 2 MichaelDun
begin
39
        priencout2      <=      priencout1;
40
        priencout3      <=      priencout2;
41 4 MichaelDun
        barrelin        <=      DIN[22:3];
42 2 MichaelDun
end
43
 
44
 
45 4 MichaelDun
wire [19:0] tmp1 =       (barrelin << ~priencout1);      // Barrel shifter - OMG, it's a primitive in Verilog!
46
always @(posedge clk)
47 2 MichaelDun
begin
48
        barrelout       <=      tmp1[19:15];
49
end
50
 
51
 
52
 
53
wire    [15:0]   priencin = DIN[23:8];
54
 
55
always @(posedge clk)                                           // Priority encoder
56
 
57
casex (priencin)
58
 
59
        16'b1xxxxxxxxxxxxxxx:   priencout1      <=      15;
60
        16'b01xxxxxxxxxxxxxx:   priencout1      <=      14;
61
        16'b001xxxxxxxxxxxxx:   priencout1      <=      13;
62
        16'b0001xxxxxxxxxxxx:   priencout1      <=      12;
63
        16'b00001xxxxxxxxxxx:   priencout1      <=      11;
64
        16'b000001xxxxxxxxxx:   priencout1      <=      10;
65
        16'b0000001xxxxxxxxx:   priencout1      <=      9;
66
        16'b00000001xxxxxxxx:   priencout1      <=      8;
67
        16'b000000001xxxxxxx:   priencout1      <=      7;
68
        16'b0000000001xxxxxx:   priencout1      <=      6;
69
        16'b00000000001xxxxx:   priencout1      <=      5;
70
        16'b000000000001xxxx:   priencout1      <=      4;
71
        16'b0000000000001xxx:   priencout1      <=      3;
72
        16'b00000000000001xx:   priencout1      <=      2;
73
        16'b000000000000001x:   priencout1      <=      1;
74
        16'b000000000000000x:   priencout1      <=      0;
75
 
76
endcase
77
 
78
 
79 4 MichaelDun
 
80 2 MichaelDun
/*
81
LUT for log fraction lookup
82
 - can be done with array or case:
83
 
84
case (addr)
85
0:out=0;
86
.
87
31:out=15;
88
endcase
89
 
90
        OR
91
 
92
wire [3:0] lut [0:31];
93
assign lut[0] = 0;
94
.
95
assign lut[31] = 15;
96
 
97
Are there any better ways?
98
*/
99
 
100
// Let's try "case".
101
// The equation is: output = log2(1+input/32)*16
102
// For larger tables, better to generate a separate data file using a program!
103
 
104
always @(posedge clk)
105
case (barrelout)
106
 
107
        0:       LUTout  <=      0;
108
        1:      LUTout  <=      1;
109
        2:      LUTout  <=      1;
110
        3:      LUTout  <=      2;
111
        4:      LUTout  <=      3;
112
        5:      LUTout  <=      3;
113
        6:      LUTout  <=      4;
114
        7:      LUTout  <=      5;
115
        8:      LUTout  <=      5;
116
        9:      LUTout  <=      6;
117
        10:     LUTout  <=      6;
118
        11:     LUTout  <=      7;
119
        12:     LUTout  <=      7;
120
        13:     LUTout  <=      8;
121
        14:     LUTout  <=      8;
122
        15:     LUTout  <=      9;
123
        16:     LUTout  <=      9;
124
        17:     LUTout  <=      10;
125
        18:     LUTout  <=      10;
126
        19:     LUTout  <=      11;
127
        20:     LUTout  <=      11;
128
        21:     LUTout  <=      12;
129
        22:     LUTout  <=      12;
130
        23:     LUTout  <=      13;
131
        24:     LUTout  <=      13;
132
        25:     LUTout  <=      13;
133
        26:     LUTout  <=      14;
134
        27:     LUTout  <=      14;
135
        28:     LUTout  <=      14;     // calculated value is *slightly* closer to 15, but 14 makes for a smoother curve!
136
        29:     LUTout  <=      15;
137
        30:     LUTout  <=      15;
138
        31:     LUTout  <=      15;
139
 
140
endcase
141
 
142
endmodule

powered by: WebSVN 2.1.0

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