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

Subversion Repositories gng

[/] [gng/] [trunk/] [rtl/] [gng_interp.v] - Blame information for rev 7

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 guangxi.li
//------------------------------------------------------------------------------
2
//
3
// gng_interp.v
4
//
5
// This file is part of the Gaussian Noise Generator IP Core
6
//
7
// Description
8
//     Polynomial interpolation.
9
//
10
//------------------------------------------------------------------------------
11
//
12
// Copyright (C) 2014, Guangxi Liu <guangxi.liu@opencores.org>
13
//
14
// This source file may be used and distributed without restriction provided
15
// that this copyright statement is not removed from the file and that any
16
// derivative work contains the original copyright notice and the associated
17
// disclaimer.
18
//
19
// This source file is free software; you can redistribute it and/or modify it
20
// under the terms of the GNU Lesser General Public License as published by
21
// the Free Software Foundation; either version 2.1 of the License,
22
// or (at your option) any later version.
23
//
24
// This source is distributed in the hope that it will be useful, but
25
// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
26
// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
27
// License for more details.
28
//
29
// You should have received a copy of the GNU Lesser General Public License
30
// along with this source; if not, download it from
31
// http://www.opencores.org/lgpl.shtml
32
//
33
//------------------------------------------------------------------------------
34
 
35
 
36
`timescale 1 ns / 1 ps
37
 
38
 
39
module gng_interp (
40
    // System signals
41
    input clk,                    // system clock
42
    input rstn,                   // system synchronous reset, active low
43
 
44
    // Data interface
45
    input valid_in,               // input data valid
46
    input [63:0] data_in,         // input data
47
    output reg valid_out,         // output data valid
48
    output reg [15:0] data_out    // output data, s<16,11>
49
);
50
 
51
// Local variables
52
wire [5:0] num_lzd;
53
reg [5:0] num_lzd_r;
54
reg [14:0] mask;
55
reg [1:0] offset;
56
wire [7:0] addr;
57
wire [17:0] c0;    // u<18,14>
58
wire [17:0] c1;    // s<18,19>
59
wire [16:0] c2;    // u<17,23>
60
reg [14:0] x;      // u<15,15>
61
reg [14:0] x_r1, x_r2, x_r3, x_r4;   // u<15,15>
62
reg [17:0] c1_r1;    // s<18,19>
63
wire [37:0] sum1;    // s<38,38>
64
wire [17:0] sum1_new;    // s<18,18>
65
wire [33:0] mul1;    // s<34,33>
66
wire signed [13:0] mul1_new;    // s<14,14>
67
reg [17:0] c0_r1, c0_r2, c0_r3, c0_r4, c0_r5;   // u<18,14>
68
reg signed [18:0] sum2;    // s<19,14>
69
reg [14:0] sum2_rnd;    // u<15,11>
70
reg [8:0] sign_r;
71
reg [8:0] valid_in_r;
72
 
73
 
74
// Leading zero detector
75
gng_lzd u_gng_lzd (
76
    .data_in(data_in[63:3]),
77
    .data_out(num_lzd)
78
);
79
 
80
always @ (posedge clk) begin
81
    if (!rstn)
82
        num_lzd_r <= 6'd0;
83
    else
84
        num_lzd_r <= num_lzd;
85
end
86
 
87
 
88
// Get mask for value x
89
always @ (posedge clk) begin
90
    if (!rstn)
91
        mask <= 15'b111111111111111;
92
    else begin
93
        case (num_lzd_r)
94
            6'd61:   mask <= 15'b111111111111111;
95
            6'd60:   mask <= 15'b011111111111111;
96
            6'd59:   mask <= 15'b101111111111111;
97
            6'd58:   mask <= 15'b110111111111111;
98
            6'd57:   mask <= 15'b111011111111111;
99
            6'd56:   mask <= 15'b111101111111111;
100
            6'd55:   mask <= 15'b111110111111111;
101
            6'd54:   mask <= 15'b111111011111111;
102
            6'd53:   mask <= 15'b111111101111111;
103
            6'd52:   mask <= 15'b111111110111111;
104
            6'd51:   mask <= 15'b111111111011111;
105
            6'd50:   mask <= 15'b111111111101111;
106
            6'd49:   mask <= 15'b111111111110111;
107
            6'd48:   mask <= 15'b111111111111011;
108
            6'd47:   mask <= 15'b111111111111101;
109
            6'd46:   mask <= 15'b111111111111110;
110
            default: mask <= 15'b111111111111111;
111
        endcase
112
    end
113
end
114
 
115
 
116
// Generate table address and coefficients
117
always @ (posedge clk) begin
118
    if (!rstn)
119
        offset <= 2'd0;
120
    else
121
        offset <= {data_in[1], data_in[2]};
122
end
123
 
124
assign addr = {num_lzd_r, offset};
125
 
126
gng_coef u_gng_coef (
127
    .clk(clk),
128
    .addr(addr),
129
    .c0(c0),
130
    .c1(c1),
131
    .c2(c2)
132
);
133
 
134
 
135
// Data delay
136
always @ (posedge clk) begin
137
    if (!rstn)
138
        x <= 15'd0;
139
    else
140
        x <= {data_in[3], data_in[4], data_in[5], data_in[6], data_in[7],
141
              data_in[8], data_in[9], data_in[10], data_in[11], data_in[12],
142
              data_in[13], data_in[14], data_in[15], data_in[16], data_in[17]};
143
end
144
 
145
always @ (posedge clk) begin
146
    x_r1 <= x & mask;
147
    x_r2 <= x_r1;
148
    x_r3 <= x_r2;
149
    x_r4 <= x_r3;
150
end
151
 
152
always @ (posedge clk) begin
153
    c1_r1 <= c1;
154
end
155
 
156
always @ (posedge clk) begin
157
    c0_r1 <= c0;
158
    c0_r2 <= c0_r1;
159
    c0_r3 <= c0_r2;
160
    c0_r4 <= c0_r3;
161
    c0_r5 <= c0_r4;
162
end
163
 
164
always @ (posedge clk) begin
165
    sign_r <= {sign_r[7:0], data_in[0]};
166
end
167
 
168
always @ (posedge clk) begin
169 7 guangxi.li
    if (!rstn)
170
        valid_in_r <= 9'd0;
171
    else
172
        valid_in_r <= {valid_in_r[7:0], valid_in};
173 2 guangxi.li
end
174
 
175
 
176
// Polynomial interpolation of order 2
177
gng_smul_16_18_sadd_37 u_gng_smul_16_18_sadd_37 (
178
    .clk(clk),
179
    .a({1'b0, x_r1}),
180
    .b({1'b0, c2}),
181
    .c({c1_r1, 19'd0}),
182
    .p(sum1)
183
);
184
 
185
assign sum1_new = sum1[37:20];
186
 
187
gng_smul_16_18 u_gng_smul_16_18 (
188
    .clk(clk),
189
    .a({1'b0, x_r4}),
190
    .b(sum1_new),
191
    .p(mul1)
192
);
193
 
194
assign mul1_new = mul1[32:19];
195
 
196
always @ (posedge clk) begin
197
    sum2 <= $signed({1'b0, c0_r5}) + mul1_new;
198
end
199
 
200
always @ (posedge clk) begin
201
    sum2_rnd <= sum2[17:3] + sum2[2];
202
end
203
 
204
 
205
// Output data
206
always @ (posedge clk) begin
207
    if (!rstn)
208
        valid_out <= 1'b0;
209
    else
210
        valid_out <= valid_in_r[8];
211
end
212
 
213
always @ (posedge clk) begin
214
    if (!rstn)
215
        data_out <= 16'd0;
216
    else if (sign_r[8])
217
        data_out <= {1'b1, ~sum2_rnd} + 1'b1;
218
    else
219
        data_out <= {1'b0, sum2_rnd};
220
end
221
 
222
 
223
endmodule

powered by: WebSVN 2.1.0

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