source: sandbox/MultiChannelUSB/cic_filter.v@ 132

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

first more or less working version

File size: 7.1 KB
RevLine 
[108]1module cic_filter
[107]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
[123]14 localparam widthr = width + 16;
[107]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;
[122]21 reg int_flag_reg, int_flag_next;
[107]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
[121]28 reg [size*widthr-1:0] acc_data_reg [3:0], acc_data_next [3:0];
[122]29 reg [size*widthr-1:0] int_data_reg [12:0], int_data_next [12:0];
[107]30
[121]31 wire [size*widthr-1:0] acc_data_wire [3:0], del_data_wire [1:0];
[107]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
[119]42
[121]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};
[119]47
[121]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];
[119]51
[121]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];
[107]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 #(
[122]71 .lpm_size(4),
[107]72 .lpm_type("LPM_MUX"),
73 .lpm_width(10),
74 .lpm_widths(2)) mux_unit_1 (
75 .sel(int_chan_next),
76 .data({
[123]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],
[107]80 2'd0, int_lfsr_reg[2*3+3:2*3], int_lfsr_reg[3+3:3]}),
[123]81 .result(int_addr_wire));
[107]82
83 always @(posedge clock)
84 begin
85 if (reset)
86 begin
87 int_wren_reg <= 1'b1;
[122]88 int_flag_reg <= 1'b0;
[107]89 int_chan_reg <= 2'd0;
90 int_case_reg <= 3'd0;
91 int_addr_reg <= 8'd0;
[121]92 for(i = 0; i <= 3; i = i + 1)
[107]93 begin
94 acc_data_reg[i] <= {(size*widthr){1'b0}};
95 end
[122]96 for(i = 0; i <= 12; i = i + 1)
[107]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;
[122]105 int_flag_reg <= int_flag_next;
[107]106 int_chan_reg <= int_chan_next;
107 int_case_reg <= int_case_next;
108 int_addr_reg <= int_addr_next;
[121]109 for(i = 0; i <= 3; i = i + 1)
[107]110 begin
111 acc_data_reg[i] <= acc_data_next[i];
112 end
[122]113 for(i = 0; i <= 12; i = i + 1)
[107]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;
[122]124 int_flag_next = int_flag_reg;
[107]125 int_chan_next = int_chan_reg;
126 int_case_next = int_case_reg;
127 int_addr_next = int_addr_reg;
[121]128 for(i = 0; i <= 3; i = i + 1)
[107]129 begin
130 acc_data_next[i] = acc_data_reg[i];
131 end
[122]132 for(i = 0; i <= 12; i = i + 1)
[107]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;
[121]144 for(i = 0; i <= 3; i = i + 1)
[107]145 begin
146 acc_data_next[i] = {(size*widthr){1'b0}};
147 end
[122]148 for(i = 0; i <= 12; i = i + 1)
[107]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;
[122]161 int_flag_next = 1'b0;
[107]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
[122]169 int_flag_next = 1'b0;
[107]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];
[121]183 acc_data_next[3] = int_data_reg[2];
[107]184
185 int_case_next = 3'd3;
186 end
[122]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
[107]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
[121]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];
[107]207
208 // register 1st sum
209 int_data_next[0] = acc_data_wire[1];
210 int_data_next[1] = acc_data_wire[2];
[121]211 int_data_next[2] = acc_data_wire[3];
[107]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
[122]219 // set read addr for 4th pipeline
220 int_chan_next = 2'd3;
221
[107]222 // prepare registers for 3rd sum
[121]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];
[107]227
228 // register 2nd sum
[121]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];
[107]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
[122]239 int_flag_next = 1'b1;
[107]240
[122]241 int_addr_next = {4'd3, int_lfsr_reg[4:1]};
242
[107]243 // set read addr for 1st pipeline
244 int_chan_next = 2'd0;
245
[122]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
[107]252 // register 3rd sum
[121]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];
[122]256
257 // register 4th output
258 int_data_next[12] = int_data_reg[11];
[107]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
[122]269 assign out_data = int_data_reg[5];
270 assign out_data2 = int_data_reg[8];
271 assign out_data3 = int_data_reg[12];
[107]272
273endmodule
Note: See TracBrowser for help on using the repository browser.