source: sandbox/MultiChannelUSB/clip.v@ 140

Last change on this file since 140 was 139, checked in by demin, 13 years ago

add signal clipping module

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