source: sandbox/MultiChannelUSB/average.v@ 115

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

add moving average module

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