source: sandbox/MultiChannelUSB/clip.v@ 167

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

add configuration registers for the clip module

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