source: sandbox/MultiChannelUSB/filter.v@ 148

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

remove test outputs

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