source: sandbox/MultiChannelUSB/deconv.v@ 116

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

fix sign conversion

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