source: sandbox/MultiChannelUSB/cic_filter.v@ 146

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

first more or less working version

File size: 7.1 KB
Line 
1module cic_filter
2 #(
3 parameter size = 3, // number of channels
4 parameter width = 12 // bit width of the input data (unsigned)
5 )
6 (
7 input wire clock, frame, reset,
8 input wire [size*width-1:0] inp_data,
9 output wire [size*widthr-1:0] out_data,
10 output wire [size*widthr-1:0] out_data2,
11 output wire [size*widthr-1:0] out_data3
12 );
13
14 localparam widthr = width + 16;
15 /*
16 4-bit LFSR with additional bits to keep track of previous values
17 */
18 reg [15:0] int_lfsr_reg, int_lfsr_next;
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 wire [9:0] int_addr_wire;
27
28 reg [size*widthr-1:0] acc_data_reg [3:0], acc_data_next [3:0];
29 reg [size*widthr-1:0] int_data_reg [12:0], int_data_next [12:0];
30
31 wire [size*widthr-1:0] acc_data_wire [3:0], del_data_wire [1:0];
32
33 integer i;
34 genvar j;
35
36 generate
37 for (j = 0; j < size; j = j + 1)
38 begin : INT_DATA
39 assign acc_data_wire[0][j*widthr+widthr-1:j*widthr] = {{(widthr-width){1'b0}}, inp_data[j*width+width-1:j*width]};
40
41 // -2*del_data_1 + del_data_2 + inp_data + result
42
43 assign acc_data_wire[1][j*widthr+widthr-1:j*widthr] =
44 acc_data_reg[0][j*widthr+widthr-1:j*widthr]
45 + del_data_wire[1][j*widthr+widthr-1:j*widthr]
46 - {del_data_wire[0][j*widthr+widthr-1],del_data_wire[0][j*widthr+widthr-3:j*widthr], 1'b0};
47
48 assign acc_data_wire[2][j*widthr+widthr-1:j*widthr] =
49 acc_data_reg[1][j*widthr+widthr-1:j*widthr]
50 + acc_data_reg[2][j*widthr+widthr-1:j*widthr];
51
52 assign acc_data_wire[3][j*widthr+widthr-1:j*widthr] =
53 acc_data_reg[2][j*widthr+widthr-1:j*widthr]
54 + acc_data_reg[3][j*widthr+widthr-1:j*widthr];
55
56 end
57 endgenerate
58
59 cic_pipeline #(
60 .width(size*widthr)) cic_pipeline_unit (
61 .clock(clock),
62 .data(acc_data_reg[0]),
63 .rdaddress_a({int_addr_wire[9:8], int_addr_wire[3:0]}),
64 .rdaddress_b({int_addr_wire[9:8], int_addr_wire[7:4]}),
65 .wraddress(int_addr_reg),
66 .wren(int_wren_reg),
67 .qa(del_data_wire[0]),
68 .qb(del_data_wire[1]));
69
70 lpm_mux #(
71 .lpm_size(4),
72 .lpm_type("LPM_MUX"),
73 .lpm_width(10),
74 .lpm_widths(2)) mux_unit_1 (
75 .sel(int_chan_next),
76 .data({
77 2'd3, int_lfsr_reg[2*5+3:2*5], int_lfsr_reg[5+3:5],
78 2'd2, int_lfsr_reg[2*4+3:2*4], int_lfsr_reg[4+3:4],
79 2'd1, int_lfsr_reg[2*3+3:2*3], int_lfsr_reg[3+3:3],
80 2'd0, int_lfsr_reg[2*3+3:2*3], int_lfsr_reg[3+3:3]}),
81 .result(int_addr_wire));
82
83 always @(posedge clock)
84 begin
85 if (reset)
86 begin
87 int_wren_reg <= 1'b1;
88 int_flag_reg <= 1'b0;
89 int_chan_reg <= 2'd0;
90 int_case_reg <= 3'd0;
91 int_addr_reg <= 8'd0;
92 for(i = 0; i <= 3; i = i + 1)
93 begin
94 acc_data_reg[i] <= {(size*widthr){1'b0}};
95 end
96 for(i = 0; i <= 12; i = i + 1)
97 begin
98 int_data_reg[i] <= {(size*widthr){1'b0}};
99 end
100 int_lfsr_reg <= 16'd0;
101 end
102 else
103 begin
104 int_wren_reg <= int_wren_next;
105 int_flag_reg <= int_flag_next;
106 int_chan_reg <= int_chan_next;
107 int_case_reg <= int_case_next;
108 int_addr_reg <= int_addr_next;
109 for(i = 0; i <= 3; i = i + 1)
110 begin
111 acc_data_reg[i] <= acc_data_next[i];
112 end
113 for(i = 0; i <= 12; i = i + 1)
114 begin
115 int_data_reg[i] <= int_data_next[i];
116 end
117 int_lfsr_reg <= int_lfsr_next;
118 end
119 end
120
121 always @*
122 begin
123 int_wren_next = int_wren_reg;
124 int_flag_next = int_flag_reg;
125 int_chan_next = int_chan_reg;
126 int_case_next = int_case_reg;
127 int_addr_next = int_addr_reg;
128 for(i = 0; i <= 3; i = i + 1)
129 begin
130 acc_data_next[i] = acc_data_reg[i];
131 end
132 for(i = 0; i <= 12; i = i + 1)
133 begin
134 int_data_next[i] = int_data_reg[i];
135 end
136 int_lfsr_next = int_lfsr_reg;
137
138 case (int_case_reg)
139 0:
140 begin
141 // write zeros
142 int_wren_next = 1'b1;
143 int_addr_next = 8'd0;
144 for(i = 0; i <= 3; i = i + 1)
145 begin
146 acc_data_next[i] = {(size*widthr){1'b0}};
147 end
148 for(i = 0; i <= 12; i = i + 1)
149 begin
150 int_data_next[i] = {(size*widthr){1'b0}};
151 end
152 int_case_next = 3'd1;
153 end
154 1:
155 begin
156 // write zeros
157 int_addr_next = int_addr_reg + 8'd1;
158 if (&int_addr_reg)
159 begin
160 int_wren_next = 1'b0;
161 int_flag_next = 1'b0;
162 int_chan_next = 2'd0;
163 int_lfsr_next = 16'h7650;
164 int_case_next = 3'd2;
165 end
166 end
167 2: // frame
168 begin
169 int_flag_next = 1'b0;
170 if (frame)
171 begin
172 int_wren_next = 1'b1;
173
174 int_addr_next = {4'd0, int_lfsr_reg[3:0]};
175
176 // set read addr for 2nd pipeline
177 int_chan_next = 2'd1;
178
179 // prepare registers for 1st sum
180 acc_data_next[0] = acc_data_wire[0];
181 acc_data_next[1] = int_data_reg[0];
182 acc_data_next[2] = int_data_reg[1];
183 acc_data_next[3] = int_data_reg[2];
184
185 int_case_next = 3'd3;
186 end
187 if (int_flag_reg) // register 4th sum
188 begin
189 // register 4th sum
190 int_data_next[9] = acc_data_wire[1];
191 int_data_next[10] = acc_data_wire[2];
192 int_data_next[11] = acc_data_wire[3];
193 end
194 end
195 3: // 1st sum
196 begin
197 int_addr_next = {4'd1, int_lfsr_reg[3:0]};
198
199 // set read addr for 3rd pipeline
200 int_chan_next = 2'd2;
201
202 // prepare registers for 2nd sum
203 acc_data_next[0] = int_data_reg[2];
204 acc_data_next[1] = int_data_reg[3];
205 acc_data_next[2] = int_data_reg[4];
206 acc_data_next[3] = int_data_reg[5];
207
208 // register 1st sum
209 int_data_next[0] = acc_data_wire[1];
210 int_data_next[1] = acc_data_wire[2];
211 int_data_next[2] = acc_data_wire[3];
212
213 int_case_next = 3'd4;
214 end
215 4: // 2nd sum
216 begin
217 int_addr_next = {4'd2, int_lfsr_reg[3:0]};
218
219 // set read addr for 4th pipeline
220 int_chan_next = 2'd3;
221
222 // prepare registers for 3rd sum
223 acc_data_next[0] = int_data_reg[5];
224 acc_data_next[1] = int_data_reg[6];
225 acc_data_next[2] = int_data_reg[7];
226 acc_data_next[3] = int_data_reg[8];
227
228 // register 2nd sum
229 int_data_next[3] = acc_data_wire[1];
230 int_data_next[4] = acc_data_wire[2];
231 int_data_next[5] = acc_data_wire[3];
232
233 int_lfsr_next = {int_lfsr_reg[14:0], int_lfsr_reg[2] ~^ int_lfsr_reg[3]};
234
235 int_case_next = 3'd5;
236 end
237 5: // 3rd sum
238 begin
239 int_flag_next = 1'b1;
240
241 int_addr_next = {4'd3, int_lfsr_reg[4:1]};
242
243 // set read addr for 1st pipeline
244 int_chan_next = 2'd0;
245
246 // prepare registers for 4th sum
247 acc_data_next[0] = int_data_reg[8];
248 acc_data_next[1] = int_data_reg[9];
249 acc_data_next[2] = int_data_reg[10];
250 acc_data_next[3] = int_data_reg[11];
251
252 // register 3rd sum
253 int_data_next[6] = acc_data_wire[1];
254 int_data_next[7] = acc_data_wire[2];
255 int_data_next[8] = acc_data_wire[3];
256
257 // register 4th output
258 int_data_next[12] = int_data_reg[11];
259
260 int_case_next = 3'd2;
261 end
262 default:
263 begin
264 int_case_next = 3'd0;
265 end
266 endcase
267 end
268
269 assign out_data = int_data_reg[5];
270 assign out_data2 = int_data_reg[8];
271 assign out_data3 = int_data_reg[12];
272
273endmodule
Note: See TracBrowser for help on using the repository browser.