source: sandbox/MultiChannelUSB/deconv.v@ 128

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

reduce bit width of the amplification parameter

File size: 10.9 KB
RevLine 
[113]1module deconv
2 #(
3 parameter size = 1, // number of channels
[123]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
[113]7 )
8 (
9 input wire clock, frame, reset,
[114]10 input wire [3*size*6-1:0] del_data,
[125]11 input wire [3*size*4-1:0] amp_data,
[114]12 input wire [3*size*16-1:0] tau_data,
[113]13 input wire [3*size*width-1:0] inp_data,
[116]14 output wire [3*size*widthr-1:0] out_data
[113]15 );
16
[114]17 localparam width1 = width + 1;
18 localparam width2 = width + 6 + 1;
[123]19 localparam width3 = width + 16 + 3;
[113]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
[114]26 reg [5:0] del_addr_reg, del_addr_next;
27 wire [5:0] del_addr_wire;
[113]28 wire [7:0] int_addr_wire;
29
[114]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;
[113]32
[123]33 wire [size*width3-1:0] add_data_wire;
[120]34
[123]35 wire [size*width3-1:0] mul_data_wire [1:0];
[113]36
[114]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;
[113]39
[114]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
[125]45 reg [size*4-1:0] amp_data_reg, amp_data_next;
46 wire [size*4-1:0] amp_data_wire [2:0];
[114]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
[113]51 integer i;
52 genvar j;
53
54 generate
55 for (j = 0; j < size; j = j + 1)
56 begin : INT_DATA
[114]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];
[125]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];
[114]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];
[113]66
[114]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
[113]79 lpm_add_sub #(
[114]80 .lpm_direction("SUB"),
[113]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 (
[114]85 .dataa(del_addr_reg),
[113]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"),
[114]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]));
[113]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"),
[114]104 .lpm_width(width2)) acc_unit_1 (
[118]105 .dataa({{(width2-width1+1){sub_data_wire[j*width1+width1-1]}}, sub_data_wire[j*width1+width1-2:j*width1]}),
[114]106 .datab(acc_data_reg[0][j*width2+width2-1:j*width2]),
107 .result(acc_data_wire[j*width2+width2-1:j*width2]));
[113]108
109 lpm_mult #(
110 .lpm_hint("MAXIMIZE_SPEED=9"),
111 .lpm_representation("SIGNED"),
112 .lpm_type("LPM_MULT"),
113 .lpm_pipeline(3),
[114]114 .lpm_widtha(width1),
115 .lpm_widthb(17),
[123]116 .lpm_widthp(width3)) mult_unit_1 (
[113]117 .clock(clock),
118 .clken(int_wren_reg),
[117]119 .dataa(sub_data_wire[j*width1+width1-1:j*width1]),
[114]120 .datab({1'b0, tau_data_reg[j*16+16-1:j*16]}),
[123]121 .result(mul_data_wire[0][j*width3+width3-1:j*width3]));
[113]122
123 lpm_mult #(
124 .lpm_hint("MAXIMIZE_SPEED=9"),
[114]125 .lpm_representation("UNSIGNED"),
[113]126 .lpm_type("LPM_MULT"),
127 .lpm_pipeline(3),
[114]128 .lpm_widtha(width2),
[125]129 .lpm_widthb(4),
[123]130 .lpm_widthp(width3)) mult_unit_2 (
[113]131 .clock(clock),
132 .clken(int_wren_reg),
[114]133 .dataa(acc_data_reg[0][j*width2+width2-1:j*width2]),
[125]134 .datab(amp_data_reg[j*4+4-1:j*4]),
[123]135 .result(mul_data_wire[1][j*width3+width3-1:j*width3]));
[113]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"),
[123]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]));
[113]146
[120]147
[123]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]}),
[120]156 .result(out_data_wire[j*widthr+widthr-1:j*widthr]));
157
[113]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),
[114]179 .width_a(size*width),
180 .width_b(size*width),
[113]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}),
[114]186 .data_a(inp_data_reg[0]),
187 .q_b(inp_data_wire[3]),
[113]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),
[114]199 .data_b({(size*width){1'b1}}),
[113]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;
[114]213 del_addr_reg <= 6'd0;
[113]214 int_addr_reg <= 8'd0;
[125]215 amp_data_reg <= 4'd0;
[114]216 tau_data_reg <= 16'd0;
217 for(i = 0; i <= 2; i = i + 1)
[113]218 begin
[114]219 inp_data_reg[i] <= {(size*width){1'b0}};
220 out_data_reg[i] <= {(size*widthr){1'b0}};
[113]221 end
[114]222 for(i = 0; i <= 3; i = i + 1)
[113]223 begin
[114]224 acc_data_reg[i] <= {(size*width2){1'b0}};
[113]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;
[114]232 del_addr_reg <= del_addr_next;
[113]233 int_addr_reg <= int_addr_next;
[114]234 amp_data_reg <= amp_data_next;
235 tau_data_reg <= tau_data_next;
236 for(i = 0; i <= 2; i = i + 1)
[113]237 begin
[114]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
[113]243 acc_data_reg[i] <= acc_data_next[i];
[114]244 end
[113]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;
[114]253 del_addr_next = del_addr_reg;
[113]254 int_addr_next = int_addr_reg;
[114]255 amp_data_next = amp_data_reg;
256 tau_data_next = tau_data_reg;
257 for(i = 0; i <= 2; i = i + 1)
[113]258 begin
[114]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
[113]264 acc_data_next[i] = acc_data_reg[i];
[114]265 end
[113]266
267 case (int_case_reg)
268 0:
269 begin
270 // write zeros
271 int_wren_next = 1'b1;
[114]272 del_addr_next = 6'd0;
[113]273 int_addr_next = 8'd0;
[125]274 amp_data_next = 4'd0;
[114]275 tau_data_next = 16'd0;
276 for(i = 0; i <= 2; i = i + 1)
[113]277 begin
[114]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)
[113]282 begin
[114]283 acc_data_next[i] = {(size*width2){1'b0}};
284 end
285
[113]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
[114]311 inp_data_next[1] = inp_data_wire[1];
312 inp_data_next[2] = inp_data_wire[2];
[113]313
314 // prepare registers for 1st sum
[114]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
[113]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
[114]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
[113]339 // register 1st sum
[114]340 acc_data_next[1] = acc_data_wire;
341 out_data_next[0] = out_data_wire;
[113]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
[114]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];
[113]355
356 // register 2nd sum
[114]357 acc_data_next[2] = acc_data_wire;
358 out_data_next[1] = out_data_wire;
[113]359
[114]360 del_addr_next = del_addr_reg + 6'd1;
361
[113]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
[114]372 acc_data_next[3] = acc_data_wire;
373 out_data_next[2] = out_data_wire;
[113]374
[114]375 int_addr_next[5:0] = del_addr_reg;
[113]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
[114]386 assign out_data = {out_data_reg[2], out_data_reg[1], out_data_reg[0]};
[113]387
388endmodule
Note: See TracBrowser for help on using the repository browser.