source: sandbox/MultiChannelUSB/deconv.v@ 125

Last change on this file since 125 was 125, checked in by demin, 14 years ago

reduce bit width of the amplification parameter

File size: 10.9 KB
Line 
1module deconv
2 #(
3 parameter size = 1, // number of channels
4 parameter shift = 24, // right shift of the result
5 parameter width = 27, // bit width of the input data
6 parameter widthr = 13 // bit width of the output data
7 )
8 (
9 input wire clock, frame, reset,
10 input wire [3*size*6-1:0] del_data,
11 input wire [3*size*4-1:0] amp_data,
12 input wire [3*size*16-1:0] tau_data,
13 input wire [3*size*width-1:0] inp_data,
14 output wire [3*size*widthr-1:0] out_data
15 );
16
17 localparam width1 = width + 1;
18 localparam width2 = width + 6 + 1;
19 localparam width3 = width + 16 + 3;
20
21 reg int_wren_reg, int_wren_next;
22 reg [1:0] int_chan_reg, int_chan_next;
23 reg [2:0] int_case_reg, int_case_next;
24 reg [7:0] int_addr_reg, int_addr_next;
25
26 reg [5:0] del_addr_reg, del_addr_next;
27 wire [5:0] del_addr_wire;
28 wire [7:0] int_addr_wire;
29
30 reg [size*widthr-1:0] out_data_reg [2:0], out_data_next [2:0];
31 wire [size*widthr-1:0] out_data_wire;
32
33 wire [size*width3-1:0] add_data_wire;
34
35 wire [size*width3-1:0] mul_data_wire [1:0];
36
37 reg [size*width2-1:0] acc_data_reg [3:0], acc_data_next [3:0];
38 wire [size*width2-1:0] acc_data_wire;
39
40 wire [size*width1-1:0] sub_data_wire;
41
42 reg [size*width-1:0] inp_data_reg [2:0], inp_data_next [2:0];
43 wire [size*width-1:0] inp_data_wire [3:0];
44
45 reg [size*4-1:0] amp_data_reg, amp_data_next;
46 wire [size*4-1:0] amp_data_wire [2:0];
47
48 reg [size*16-1:0] tau_data_reg, tau_data_next;
49 wire [size*16-1:0] tau_data_wire [2:0];
50
51 integer i;
52 genvar j;
53
54 generate
55 for (j = 0; j < size; j = j + 1)
56 begin : INT_DATA
57 assign inp_data_wire[0][j*width+width-1:j*width] = inp_data[(3*j+0)*width+width-1:(3*j+0)*width];
58 assign inp_data_wire[1][j*width+width-1:j*width] = inp_data[(3*j+1)*width+width-1:(3*j+1)*width];
59 assign inp_data_wire[2][j*width+width-1:j*width] = inp_data[(3*j+2)*width+width-1:(3*j+2)*width];
60 assign amp_data_wire[0][j*4+4-1:j*4] = amp_data[(3*j+0)*4+4-1:(3*j+0)*4];
61 assign amp_data_wire[1][j*4+4-1:j*4] = amp_data[(3*j+1)*4+4-1:(3*j+1)*4];
62 assign amp_data_wire[2][j*4+4-1:j*4] = amp_data[(3*j+2)*4+4-1:(3*j+2)*4];
63 assign tau_data_wire[0][j*16+16-1:j*16] = tau_data[(3*j+0)*16+16-1:(3*j+0)*16];
64 assign tau_data_wire[1][j*16+16-1:j*16] = tau_data[(3*j+1)*16+16-1:(3*j+1)*16];
65 assign tau_data_wire[2][j*16+16-1:j*16] = tau_data[(3*j+2)*16+16-1:(3*j+2)*16];
66
67 lpm_mux #(
68 .lpm_size(3),
69 .lpm_type("LPM_MUX"),
70 .lpm_width(8),
71 .lpm_widths(2)) mux_unit_1 (
72 .sel(int_chan_next),
73 .data({
74 2'd2, del_data[(3*j+2)*6+6-1:(3*j+2)*6],
75 2'd1, del_data[(3*j+1)*6+6-1:(3*j+1)*6],
76 2'd0, del_data[(3*j+0)*6+6-1:(3*j+0)*6]}),
77 .result(int_addr_wire));
78
79 lpm_add_sub #(
80 .lpm_direction("SUB"),
81 .lpm_hint("ONE_INPUT_IS_CONSTANT=NO,CIN_USED=NO"),
82 .lpm_representation("UNSIGNED"),
83 .lpm_type("LPM_ADD_SUB"),
84 .lpm_width(6)) add_unit_1 (
85 .dataa(del_addr_reg),
86 .datab(int_addr_wire[5:0]),
87 .result(del_addr_wire));
88
89 lpm_add_sub #(
90 .lpm_direction("SUB"),
91 .lpm_hint("ONE_INPUT_IS_CONSTANT=NO,CIN_USED=NO"),
92 .lpm_representation("SIGNED"),
93 .lpm_type("LPM_ADD_SUB"),
94 .lpm_width(width1)) sub_unit_1 (
95 .dataa({{(width1-width){1'b0}}, inp_data_reg[0][j*width+width-1:j*width]}),
96 .datab({{(width1-width){1'b0}}, inp_data_wire[3][j*width+width-1:j*width]}),
97 .result(sub_data_wire[j*width1+width1-1:j*width1]));
98
99 lpm_add_sub #(
100 .lpm_direction("ADD"),
101 .lpm_hint("ONE_INPUT_IS_CONSTANT=NO,CIN_USED=NO"),
102 .lpm_representation("SIGNED"),
103 .lpm_type("LPM_ADD_SUB"),
104 .lpm_width(width2)) acc_unit_1 (
105 .dataa({{(width2-width1+1){sub_data_wire[j*width1+width1-1]}}, sub_data_wire[j*width1+width1-2:j*width1]}),
106 .datab(acc_data_reg[0][j*width2+width2-1:j*width2]),
107 .result(acc_data_wire[j*width2+width2-1:j*width2]));
108
109 lpm_mult #(
110 .lpm_hint("MAXIMIZE_SPEED=9"),
111 .lpm_representation("SIGNED"),
112 .lpm_type("LPM_MULT"),
113 .lpm_pipeline(3),
114 .lpm_widtha(width1),
115 .lpm_widthb(17),
116 .lpm_widthp(width3)) mult_unit_1 (
117 .clock(clock),
118 .clken(int_wren_reg),
119 .dataa(sub_data_wire[j*width1+width1-1:j*width1]),
120 .datab({1'b0, tau_data_reg[j*16+16-1:j*16]}),
121 .result(mul_data_wire[0][j*width3+width3-1:j*width3]));
122
123 lpm_mult #(
124 .lpm_hint("MAXIMIZE_SPEED=9"),
125 .lpm_representation("UNSIGNED"),
126 .lpm_type("LPM_MULT"),
127 .lpm_pipeline(3),
128 .lpm_widtha(width2),
129 .lpm_widthb(4),
130 .lpm_widthp(width3)) mult_unit_2 (
131 .clock(clock),
132 .clken(int_wren_reg),
133 .dataa(acc_data_reg[0][j*width2+width2-1:j*width2]),
134 .datab(amp_data_reg[j*4+4-1:j*4]),
135 .result(mul_data_wire[1][j*width3+width3-1:j*width3]));
136
137 lpm_add_sub #(
138 .lpm_direction("ADD"),
139 .lpm_hint("ONE_INPUT_IS_CONSTANT=NO,CIN_USED=NO"),
140 .lpm_representation("SIGNED"),
141 .lpm_type("LPM_ADD_SUB"),
142 .lpm_width(width3)) add_unit_2 (
143 .dataa(mul_data_wire[0][j*width3+width3-1:j*width3]),
144 .datab(mul_data_wire[1][j*width3+width3-1:j*width3]),
145 .result(add_data_wire[j*width3+width3-1:j*width3]));
146
147
148 lpm_add_sub #(
149 .lpm_direction("ADD"),
150 .lpm_hint("ONE_INPUT_IS_CONSTANT=NO,CIN_USED=NO"),
151 .lpm_representation("UNSIGNED"),
152 .lpm_type("LPM_ADD_SUB"),
153 .lpm_width(widthr)) add_unit_3 (
154 .dataa(add_data_wire[j*width3+shift+widthr-1:j*width3+shift]),
155 .datab({{(widthr-1){1'b0}}, add_data_wire[j*width3+shift-1]}),
156 .result(out_data_wire[j*widthr+widthr-1:j*widthr]));
157
158 end
159 endgenerate
160
161
162 altsyncram #(
163 .address_aclr_b("NONE"),
164 .address_reg_b("CLOCK0"),
165 .clock_enable_input_a("BYPASS"),
166 .clock_enable_input_b("BYPASS"),
167 .clock_enable_output_b("BYPASS"),
168 .intended_device_family("Cyclone III"),
169 .lpm_type("altsyncram"),
170 .numwords_a(256),
171 .numwords_b(256),
172 .operation_mode("DUAL_PORT"),
173 .outdata_aclr_b("NONE"),
174 .outdata_reg_b("CLOCK0"),
175 .power_up_uninitialized("FALSE"),
176 .read_during_write_mode_mixed_ports("DONT_CARE"),
177 .widthad_a(8),
178 .widthad_b(8),
179 .width_a(size*width),
180 .width_b(size*width),
181 .width_byteena_a(1)) ram_unit_1 (
182 .wren_a(int_wren_reg),
183 .clock0(clock),
184 .address_a(int_addr_reg),
185 .address_b({int_addr_wire[7:6], del_addr_wire}),
186 .data_a(inp_data_reg[0]),
187 .q_b(inp_data_wire[3]),
188 .aclr0(1'b0),
189 .aclr1(1'b0),
190 .addressstall_a(1'b0),
191 .addressstall_b(1'b0),
192 .byteena_a(1'b1),
193 .byteena_b(1'b1),
194 .clock1(1'b1),
195 .clocken0(1'b1),
196 .clocken1(1'b1),
197 .clocken2(1'b1),
198 .clocken3(1'b1),
199 .data_b({(size*width){1'b1}}),
200 .eccstatus(),
201 .q_a(),
202 .rden_a(1'b1),
203 .rden_b(1'b1),
204 .wren_b(1'b0));
205
206 always @(posedge clock)
207 begin
208 if (reset)
209 begin
210 int_wren_reg <= 1'b1;
211 int_chan_reg <= 2'd0;
212 int_case_reg <= 3'd0;
213 del_addr_reg <= 6'd0;
214 int_addr_reg <= 8'd0;
215 amp_data_reg <= 4'd0;
216 tau_data_reg <= 16'd0;
217 for(i = 0; i <= 2; i = i + 1)
218 begin
219 inp_data_reg[i] <= {(size*width){1'b0}};
220 out_data_reg[i] <= {(size*widthr){1'b0}};
221 end
222 for(i = 0; i <= 3; i = i + 1)
223 begin
224 acc_data_reg[i] <= {(size*width2){1'b0}};
225 end
226 end
227 else
228 begin
229 int_wren_reg <= int_wren_next;
230 int_chan_reg <= int_chan_next;
231 int_case_reg <= int_case_next;
232 del_addr_reg <= del_addr_next;
233 int_addr_reg <= int_addr_next;
234 amp_data_reg <= amp_data_next;
235 tau_data_reg <= tau_data_next;
236 for(i = 0; i <= 2; i = i + 1)
237 begin
238 inp_data_reg[i] <= inp_data_next[i];
239 out_data_reg[i] <= out_data_next[i];
240 end
241 for(i = 0; i <= 3; i = i + 1)
242 begin
243 acc_data_reg[i] <= acc_data_next[i];
244 end
245 end
246 end
247
248 always @*
249 begin
250 int_wren_next = int_wren_reg;
251 int_chan_next = int_chan_reg;
252 int_case_next = int_case_reg;
253 del_addr_next = del_addr_reg;
254 int_addr_next = int_addr_reg;
255 amp_data_next = amp_data_reg;
256 tau_data_next = tau_data_reg;
257 for(i = 0; i <= 2; i = i + 1)
258 begin
259 inp_data_next[i] = inp_data_reg[i];
260 out_data_next[i] = out_data_reg[i];
261 end
262 for(i = 0; i <= 3; i = i + 1)
263 begin
264 acc_data_next[i] = acc_data_reg[i];
265 end
266
267 case (int_case_reg)
268 0:
269 begin
270 // write zeros
271 int_wren_next = 1'b1;
272 del_addr_next = 6'd0;
273 int_addr_next = 8'd0;
274 amp_data_next = 4'd0;
275 tau_data_next = 16'd0;
276 for(i = 0; i <= 2; i = i + 1)
277 begin
278 inp_data_next[i] = {(size*width){1'b0}};
279 out_data_next[i] = {(size*widthr){1'b0}};
280 end
281 for(i = 0; i <= 3; i = i + 1)
282 begin
283 acc_data_next[i] = {(size*width2){1'b0}};
284 end
285
286 int_case_next = 3'd1;
287 end
288 1:
289 begin
290 // write zeros
291 int_addr_next = int_addr_reg + 8'd1;
292 if (&int_addr_reg)
293 begin
294 int_wren_next = 1'b0;
295 int_chan_next = 2'd0;
296 int_case_next = 3'd2;
297 end
298 end
299 2: // frame
300 begin
301 if (frame)
302 begin
303 int_wren_next = 1'b1;
304
305 int_addr_next[7:6] = 2'd0;
306
307 // set read addr for 2nd pipeline
308 int_chan_next = 2'd1;
309
310 // register input data for 2nd and 3rd sums
311 inp_data_next[1] = inp_data_wire[1];
312 inp_data_next[2] = inp_data_wire[2];
313
314 // prepare registers for 1st sum
315 inp_data_next[0] = inp_data_wire[0];
316 acc_data_next[0] = acc_data_reg[1];
317
318 tau_data_next = tau_data_wire[0];
319 amp_data_next = amp_data_wire[0];
320
321 int_case_next = 3'd3;
322 end
323
324 end
325 3: // 1st sum
326 begin
327 int_addr_next[7:6] = 2'd1;
328
329 // set read addr for 3rd pipeline
330 int_chan_next = 2'd2;
331
332 // prepare registers for 2nd sum
333 inp_data_next[0] = inp_data_reg[1];
334 acc_data_next[0] = acc_data_reg[2];
335
336 tau_data_next = tau_data_wire[1];
337 amp_data_next = amp_data_wire[1];
338
339 // register 1st sum
340 acc_data_next[1] = acc_data_wire;
341 out_data_next[0] = out_data_wire;
342
343 int_case_next = 3'd4;
344 end
345 4: // 2nd sum
346 begin
347 int_addr_next[7:6] = 2'd2;
348
349 // prepare registers for 3rd sum
350 inp_data_next[0] = inp_data_reg[2];
351 acc_data_next[0] = acc_data_reg[3];
352
353 tau_data_next = tau_data_wire[2];
354 amp_data_next = amp_data_wire[2];
355
356 // register 2nd sum
357 acc_data_next[2] = acc_data_wire;
358 out_data_next[1] = out_data_wire;
359
360 del_addr_next = del_addr_reg + 6'd1;
361
362 int_case_next = 3'd5;
363 end
364 5: // 3rd sum
365 begin
366 int_wren_next = 1'b0;
367
368 // set read addr for 1st pipeline
369 int_chan_next = 2'd0;
370
371 // register 3rd sum
372 acc_data_next[3] = acc_data_wire;
373 out_data_next[2] = out_data_wire;
374
375 int_addr_next[5:0] = del_addr_reg;
376
377 int_case_next = 3'd2;
378 end
379 default:
380 begin
381 int_case_next = 3'd0;
382 end
383 endcase
384 end
385
386 assign out_data = {out_data_reg[2], out_data_reg[1], out_data_reg[0]};
387
388endmodule
Note: See TracBrowser for help on using the repository browser.