source: sandbox/MultiChannelUSB/filter.v@ 128

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

add back the 3 stage version of the filter with a different name

File size: 6.2 KB
Line 
1module 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 + 13;
15
16 /*
17 4-bit LFSR with additional bits to keep track of previous values
18 */
19 reg [15:0] int_lfsr_reg, int_lfsr_next;
20
21 reg int_wren_reg, int_wren_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 [8:0], int_data_next [8: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(3),
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'd2, int_lfsr_reg[2*5+3:2*5], int_lfsr_reg[5+3:5],
78 2'd1, int_lfsr_reg[2*4+3:2*4], int_lfsr_reg[4+3:4],
79 2'd0, int_lfsr_reg[2*3+3:2*3], int_lfsr_reg[3+3:3]}),
80 .result(int_addr_wire));
81
82 always @(posedge clock)
83 begin
84 if (reset)
85 begin
86 int_wren_reg <= 1'b1;
87 int_chan_reg <= 2'd0;
88 int_case_reg <= 3'd0;
89 int_addr_reg <= 8'd0;
90 for(i = 0; i <= 3; i = i + 1)
91 begin
92 acc_data_reg[i] <= {(size*widthr){1'b0}};
93 end
94 for(i = 0; i <= 8; i = i + 1)
95 begin
96 int_data_reg[i] <= {(size*widthr){1'b0}};
97 end
98 int_lfsr_reg <= 16'd0;
99 end
100 else
101 begin
102 int_wren_reg <= int_wren_next;
103 int_chan_reg <= int_chan_next;
104 int_case_reg <= int_case_next;
105 int_addr_reg <= int_addr_next;
106 for(i = 0; i <= 3; i = i + 1)
107 begin
108 acc_data_reg[i] <= acc_data_next[i];
109 end
110 for(i = 0; i <= 8; i = i + 1)
111 begin
112 int_data_reg[i] <= int_data_next[i];
113 end
114 int_lfsr_reg <= int_lfsr_next;
115 end
116 end
117
118 always @*
119 begin
120 int_wren_next = int_wren_reg;
121 int_chan_next = int_chan_reg;
122 int_case_next = int_case_reg;
123 int_addr_next = int_addr_reg;
124 for(i = 0; i <= 3; i = i + 1)
125 begin
126 acc_data_next[i] = acc_data_reg[i];
127 end
128 for(i = 0; i <= 8; i = i + 1)
129 begin
130 int_data_next[i] = int_data_reg[i];
131 end
132 int_lfsr_next = int_lfsr_reg;
133
134 case (int_case_reg)
135 0:
136 begin
137 // write zeros
138 int_wren_next = 1'b1;
139 int_addr_next = 8'd0;
140 for(i = 0; i <= 3; i = i + 1)
141 begin
142 acc_data_next[i] = {(size*widthr){1'b0}};
143 end
144 for(i = 0; i <= 8; i = i + 1)
145 begin
146 int_data_next[i] = {(size*widthr){1'b0}};
147 end
148 int_case_next = 3'd1;
149 end
150 1:
151 begin
152 // write zeros
153 int_addr_next = int_addr_reg + 8'd1;
154 if (&int_addr_reg)
155 begin
156 int_wren_next = 1'b0;
157 int_chan_next = 2'd0;
158 int_lfsr_next = 16'h7650;
159 int_case_next = 3'd2;
160 end
161 end
162 2: // frame
163 begin
164 if (frame)
165 begin
166 int_wren_next = 1'b1;
167
168 int_addr_next = {4'd0, int_lfsr_reg[3:0]};
169
170 // set read addr for 2nd pipeline
171 int_chan_next = 2'd1;
172
173 // prepare registers for 1st sum
174 acc_data_next[0] = acc_data_wire[0];
175 acc_data_next[1] = int_data_reg[0];
176 acc_data_next[2] = int_data_reg[1];
177 acc_data_next[3] = int_data_reg[2];
178
179 int_case_next = 3'd3;
180 end
181
182 end
183 3: // 1st sum
184 begin
185 int_addr_next = {4'd1, int_lfsr_reg[3:0]};
186
187 // set read addr for 3rd pipeline
188 int_chan_next = 2'd2;
189
190 // prepare registers for 2nd sum
191 acc_data_next[0] = int_data_reg[2];
192 acc_data_next[1] = int_data_reg[3];
193 acc_data_next[2] = int_data_reg[4];
194 acc_data_next[3] = int_data_reg[5];
195
196 // register 1st sum
197 int_data_next[0] = acc_data_wire[1];
198 int_data_next[1] = acc_data_wire[2];
199 int_data_next[2] = acc_data_wire[3];
200
201 int_case_next = 3'd4;
202 end
203 4: // 2nd sum
204 begin
205 int_addr_next = {4'd2, int_lfsr_reg[3:0]};
206
207 // prepare registers for 3rd sum
208 acc_data_next[0] = int_data_reg[5];
209 acc_data_next[1] = int_data_reg[6];
210 acc_data_next[2] = int_data_reg[7];
211 acc_data_next[3] = int_data_reg[8];
212
213 // register 2nd sum
214 int_data_next[3] = acc_data_wire[1];
215 int_data_next[4] = acc_data_wire[2];
216 int_data_next[5] = acc_data_wire[3];
217
218 int_lfsr_next = {int_lfsr_reg[14:0], int_lfsr_reg[2] ~^ int_lfsr_reg[3]};
219
220 int_case_next = 3'd5;
221 end
222 5: // 3rd sum
223 begin
224 int_wren_next = 1'b0;
225
226 // set read addr for 1st pipeline
227 int_chan_next = 2'd0;
228
229 // register 3rd sum
230 int_data_next[6] = acc_data_wire[1];
231 int_data_next[7] = acc_data_wire[2];
232 int_data_next[8] = acc_data_wire[3];
233
234 int_case_next = 3'd2;
235 end
236 default:
237 begin
238 int_case_next = 3'd0;
239 end
240 endcase
241 end
242
243 assign out_data = int_data_reg[2];
244 assign out_data2 = int_data_reg[5];
245 assign out_data3 = int_data_reg[8];
246
247endmodule
Note: See TracBrowser for help on using the repository browser.