1 | //********************************************************************************************** |
---|
2 | // File: fec_encoder.v |
---|
3 | // Author: Yang Sun (ysun@rice.edu) |
---|
4 | // Created: 2010.10.8 |
---|
5 | //********************************************************************************************** |
---|
6 | module fec_encoder ( |
---|
7 | clk , // I, clock |
---|
8 | ce , // I, clock enable |
---|
9 | nrst , // I, n reset |
---|
10 | start , // I, start pulse |
---|
11 | coding_en , // I, coding enable |
---|
12 | pkt_done , // I, pkt transmit done |
---|
13 | fec_rd , // I, fec data request |
---|
14 | info_data , // I, info data |
---|
15 | info_scram , // I, info data scrabled |
---|
16 | info_len , // I, number of payload |
---|
17 | codeword_len , // O, number of coded data in bytes |
---|
18 | info_rd , // O, read |
---|
19 | info_raddr , // O, TX byte address |
---|
20 | fec_data // O, encoded data in bytes |
---|
21 | ) ; |
---|
22 | |
---|
23 | input clk ; |
---|
24 | input ce ; |
---|
25 | input nrst ; |
---|
26 | input start ; |
---|
27 | input coding_en ; |
---|
28 | input pkt_done ; |
---|
29 | input fec_rd ; |
---|
30 | input [7:0] info_data ; |
---|
31 | input [7:0] info_scram ; |
---|
32 | input [15:0] info_len ; |
---|
33 | output [15:0] codeword_len ; |
---|
34 | output info_rd ; |
---|
35 | output [13:0] info_raddr ; |
---|
36 | output [7:0] fec_data ; |
---|
37 | |
---|
38 | |
---|
39 | //============================ |
---|
40 | //Internal signal |
---|
41 | //============================ |
---|
42 | reg in_enc ; |
---|
43 | wire ff_half_full ; |
---|
44 | wire [7:0] ff_wdata ; |
---|
45 | wire ff_wr ; |
---|
46 | wire ff_rd ; |
---|
47 | wire [7:0] ff_rdata ; |
---|
48 | wire enc_done ; |
---|
49 | wire ffdata_req ; |
---|
50 | reg ffdata_req_d ; |
---|
51 | reg ffdata_req_dd ; |
---|
52 | reg [13:0] addr_out ; |
---|
53 | |
---|
54 | wire [7:0] sff_din_cc ; |
---|
55 | wire sff_empty_cc ; |
---|
56 | wire sff_full_cc ; |
---|
57 | wire sff_rd_cc ; |
---|
58 | wire sff_wr_cc ; |
---|
59 | wire [3:0] sff_dout_cc ; |
---|
60 | |
---|
61 | wire cc_vin ; |
---|
62 | wire [3:0] cc_din ; |
---|
63 | wire [7:0] cc_dout ; |
---|
64 | wire [7:0] cc_mask ; |
---|
65 | wire [7:0] cc_dpunct ; |
---|
66 | wire [3:0] n_cc_dpunct ; |
---|
67 | |
---|
68 | wire sff_empty_qam ; |
---|
69 | wire sff_full_qam ; |
---|
70 | wire sff_rd_qam ; |
---|
71 | wire sff_wr_qam ; |
---|
72 | wire [7:0] sff_dout_qam ; |
---|
73 | wire [7:0] sff_din_qam ; |
---|
74 | wire [3:0] sff_nsin_qam ; |
---|
75 | wire coding_en ; |
---|
76 | wire [1:0] cc_rate_mux ; |
---|
77 | reg [1:0] cc_rate ; |
---|
78 | |
---|
79 | reg [5:0] cc_cnt ; |
---|
80 | wire in_baserate_cc ; |
---|
81 | reg [7:0] fec_data_i ; |
---|
82 | wire bypass ; |
---|
83 | |
---|
84 | reg [15:0] pkt_len ; |
---|
85 | reg [15:0] info_len_lat ; |
---|
86 | reg [15:0] payload_len ; |
---|
87 | wire [15:0] payload_len_i ; |
---|
88 | |
---|
89 | wire [10:0] coe ; |
---|
90 | wire [26:0] tmp_mult ; |
---|
91 | reg [15:0] payload_coded ; |
---|
92 | |
---|
93 | //============================ |
---|
94 | // Main RTL |
---|
95 | //============================ |
---|
96 | assign info_raddr = addr_out ; |
---|
97 | assign fec_data = fec_data_i ; |
---|
98 | assign info_rd = ffdata_req_d ; |
---|
99 | assign codeword_len = pkt_len ; |
---|
100 | |
---|
101 | always @ (posedge clk or negedge nrst) |
---|
102 | if(~nrst) |
---|
103 | fec_data_i <= 0 ; |
---|
104 | else if(ce) |
---|
105 | begin |
---|
106 | if(start) |
---|
107 | fec_data_i <= 0 ; |
---|
108 | else if(fec_rd) |
---|
109 | fec_data_i <= sff_dout_qam ; |
---|
110 | end |
---|
111 | |
---|
112 | |
---|
113 | always @ (posedge clk or negedge nrst) |
---|
114 | if (~nrst) |
---|
115 | in_enc <= 1'b0 ; |
---|
116 | else if (ce) |
---|
117 | begin |
---|
118 | if (start) |
---|
119 | in_enc <= 1'b1 ; |
---|
120 | else if (pkt_done) |
---|
121 | in_enc <= 1'b0 ; |
---|
122 | end |
---|
123 | |
---|
124 | assign ffdata_req = in_enc & ~ff_half_full ; |
---|
125 | always @ (posedge clk or negedge nrst) |
---|
126 | if (~nrst) |
---|
127 | {ffdata_req_dd, ffdata_req_d} <= 2'b00 ; |
---|
128 | else if (ce) |
---|
129 | {ffdata_req_dd, ffdata_req_d} <= {ffdata_req_d, ffdata_req} ; |
---|
130 | |
---|
131 | always @ (posedge clk or negedge nrst) |
---|
132 | if (~nrst) |
---|
133 | addr_out <= 0 ; |
---|
134 | else if (ce) |
---|
135 | begin |
---|
136 | if (start) |
---|
137 | addr_out <= 0 ; |
---|
138 | else if (ffdata_req) |
---|
139 | addr_out <= addr_out +1 ; |
---|
140 | end |
---|
141 | |
---|
142 | |
---|
143 | assign ff_wr = ffdata_req_dd ; |
---|
144 | assign ff_wdata = info_scram ; |
---|
145 | assign ff_rd = sff_wr_cc ; |
---|
146 | |
---|
147 | //-- 8x8 Input FIFO |
---|
148 | fifo_async_rd #(8, 8, 3) input_fifo ( |
---|
149 | .clk (clk ), |
---|
150 | .nrst (nrst ), |
---|
151 | .ce (ce ), |
---|
152 | .reset (start ), |
---|
153 | .wdata (ff_wdata ), |
---|
154 | .wr (ff_wr ), |
---|
155 | .rd (ff_rd ), |
---|
156 | .rdata (ff_rdata ), |
---|
157 | .empty (ff_empty ), |
---|
158 | .half_full (ff_half_full ), |
---|
159 | .full (ff_full ) |
---|
160 | ) ; |
---|
161 | |
---|
162 | |
---|
163 | assign sff_din_cc = ff_rdata ; |
---|
164 | assign sff_wr_cc = (~sff_full_cc) & (~ff_empty) & in_enc ; |
---|
165 | assign sff_rd_cc = sff_wr_qam ; |
---|
166 | |
---|
167 | //-- shift fifo between input fifo and CC encoder |
---|
168 | sfifo_8to4 cc_fifo ( |
---|
169 | .clk (clk ), // clock |
---|
170 | .ce (ce ), // clock enable |
---|
171 | .nrst (nrst ), // asyn reset |
---|
172 | .reset (start ), // sync reset |
---|
173 | .din (sff_din_cc ), // data input |
---|
174 | .dout (sff_dout_cc ), // data output |
---|
175 | .rd (sff_rd_cc ), // read |
---|
176 | .wr (sff_wr_cc ), // write |
---|
177 | .full (sff_full_cc ), // fifo full |
---|
178 | .empty (sff_empty_cc ), // fifo empty |
---|
179 | .nsin (4'd8 ), // num of shift in (bits) |
---|
180 | .nsout (4'd4 ) // num of shift out (bits) |
---|
181 | ) ; |
---|
182 | |
---|
183 | // get coding rate from second byte of the header |
---|
184 | always @ (posedge clk or negedge nrst) |
---|
185 | if (~nrst) |
---|
186 | cc_rate <= 0 ; |
---|
187 | else if (ce) |
---|
188 | begin |
---|
189 | if(start) |
---|
190 | cc_rate <= 0 ; |
---|
191 | else if (info_rd & (info_raddr == 3)) // read latency is 2 |
---|
192 | cc_rate <= info_data ; |
---|
193 | end |
---|
194 | |
---|
195 | assign cc_vin = sff_wr_qam ; |
---|
196 | assign cc_din = sff_dout_cc ; |
---|
197 | assign cc_rate_mux = in_baserate_cc ? 0 : cc_rate ; |
---|
198 | |
---|
199 | //-- cc_encoder |
---|
200 | cc_encoder cc_encoder ( |
---|
201 | .clk (clk ), // I, clock |
---|
202 | .ce (ce ), // I, clock enable |
---|
203 | .nrst (nrst ), // I, n reset |
---|
204 | .cc_start (start ), // I, start pulse |
---|
205 | .rate (cc_rate_mux ), // I, code rate |
---|
206 | .vin (cc_vin ), // I, valid in |
---|
207 | .din (cc_din ), // I, parallel data input. QPSK = din[3], 16-QAM = din[3:2], 64-QAM = din[3:1], 256-QAM = din[3:0] |
---|
208 | .vout ( ), // O, encoded data out valid |
---|
209 | .dout (cc_dout ), // O, arallel data output. QPSK = dout[7:6], 16-QAM = dout[7:4], 64-QAM = dout[7:2], 256-QAM = dout[7:0] |
---|
210 | .mask (cc_mask ) // O, mask |
---|
211 | ) ; |
---|
212 | |
---|
213 | always @ (posedge clk or negedge nrst) |
---|
214 | if (~nrst) |
---|
215 | cc_cnt <= 0 ; |
---|
216 | else if (ce) |
---|
217 | begin |
---|
218 | if(start) |
---|
219 | cc_cnt <= 0 ; |
---|
220 | else if (cc_vin & in_baserate_cc) |
---|
221 | cc_cnt <= cc_cnt +1 ; |
---|
222 | end |
---|
223 | |
---|
224 | assign in_baserate_cc = cc_cnt != 48; |
---|
225 | |
---|
226 | //-- cc_puncture |
---|
227 | cc_puncture cc_puncture ( |
---|
228 | .din (cc_dout ) , // I, data in |
---|
229 | .mask (cc_mask ) , // I, data in mask |
---|
230 | .dout (cc_dpunct ) , // O, data out |
---|
231 | .ndout (n_cc_dpunct) // O, number of output bits |
---|
232 | ) ; |
---|
233 | |
---|
234 | assign sff_rd_qam = fec_rd ; |
---|
235 | assign sff_wr_qam = ((~sff_full_qam) & (~sff_empty_cc)) & in_enc ; |
---|
236 | |
---|
237 | assign bypass = (~coding_en) | (cc_rate_mux == 3) ; |
---|
238 | assign sff_din_qam = bypass ? {sff_dout_cc, 4'd0} : cc_dpunct ; |
---|
239 | assign sff_nsin_qam = bypass ? 4 : n_cc_dpunct ; |
---|
240 | |
---|
241 | //-- shift fifo between cc encoder and QAM modulator |
---|
242 | sfifo_nto8 output_fifo ( |
---|
243 | .clk (clk ), // clock |
---|
244 | .ce (ce ), // clock enable |
---|
245 | .nrst (nrst ), // asyn reset |
---|
246 | .reset (start ), // sync reset |
---|
247 | .din (sff_din_qam ), // data input |
---|
248 | .dout (sff_dout_qam ), // data output |
---|
249 | .rd (sff_rd_qam ), // read |
---|
250 | .wr (sff_wr_qam ), // write |
---|
251 | .full (sff_full_qam ), // fifo full |
---|
252 | .empty (sff_empty_qam ), // fifo empty |
---|
253 | .nsin (sff_nsin_qam ), // num of shift in (bits), could be 4, 6 or 8 |
---|
254 | .nsout (4'd8 ) // num of shift out (bits) |
---|
255 | ) ; |
---|
256 | |
---|
257 | |
---|
258 | always @(posedge clk or negedge nrst) |
---|
259 | if(~nrst) |
---|
260 | info_len_lat <= 256 ; |
---|
261 | else if(ce) |
---|
262 | info_len_lat <= info_len ; |
---|
263 | |
---|
264 | always @(posedge clk or negedge nrst) |
---|
265 | if(~nrst) |
---|
266 | payload_len <= 0 ; |
---|
267 | else if(ce) |
---|
268 | payload_len <= info_len -24 ; |
---|
269 | |
---|
270 | assign payload_len_i = {payload_len, 1'b0} ; |
---|
271 | |
---|
272 | wire [5:0] lenAdj; |
---|
273 | assign lenAdj = (info_len == 24) ? 48 : 50; |
---|
274 | |
---|
275 | always @* |
---|
276 | begin |
---|
277 | pkt_len = info_len_lat ; |
---|
278 | if(coding_en) |
---|
279 | begin |
---|
280 | case(cc_rate_mux) |
---|
281 | 2'd0: pkt_len = {info_len_lat[14:0], 1'b0} ; // rate 1/2 |
---|
282 | 2'd1: pkt_len = payload_coded +lenAdj ; // rate 2/3 |
---|
283 | 2'd2: pkt_len = payload_coded +lenAdj ; // rate 3/4 |
---|
284 | // 2'd1: pkt_len = payload_coded +50 ; // rate 2/3 |
---|
285 | // 2'd2: pkt_len = payload_coded +50 ; // rate 3/4 |
---|
286 | 2'd3: pkt_len = info_len_lat +24 ; // rate 1 |
---|
287 | endcase |
---|
288 | end |
---|
289 | else |
---|
290 | pkt_len = info_len_lat ; |
---|
291 | end |
---|
292 | |
---|
293 | // 1536 = 3/4 * 2048, 1365 = 2/3 * 2048 |
---|
294 | assign coe = (cc_rate_mux == 1) ? 1536 : 1365 ; |
---|
295 | assign tmp_mult = coe * payload_len_i ; |
---|
296 | |
---|
297 | always @(posedge clk or negedge nrst) |
---|
298 | if(~nrst) |
---|
299 | payload_coded <= 256 ; |
---|
300 | else if (ce) |
---|
301 | payload_coded <= tmp_mult[26:11] ; |
---|
302 | |
---|
303 | endmodule |
---|
304 | |
---|
305 | //************************************************************** |
---|
306 | // File: cc_encoder.v |
---|
307 | // Author: Yang Sun (ysun@rice.edu) |
---|
308 | // Created: $ 02/11/07 |
---|
309 | // Des: Convolutional encoder core |
---|
310 | // K = 7, compliant with 802.11a |
---|
311 | // u0 u1 u2 u3 -> {A0,B0}, {A1,B1}, {A2,B2}, {A3,B3} |
---|
312 | // |
---|
313 | // History: $ 02/11/07, First version, K = 5 |
---|
314 | // $ 03/31/07, Added 256-QAM |
---|
315 | // $ 04/20/07, K = 7 |
---|
316 | // $ 04/29/07, Added ce |
---|
317 | // $ 11/26/07, Remove puncture |
---|
318 | // $ 09/27/08, Added puncture |
---|
319 | // $ 10/11/08, Added uncoded and BPSK support |
---|
320 | //************************************************************** |
---|
321 | module cc_encoder ( |
---|
322 | clk , // I, clock |
---|
323 | ce , // I, clock enable |
---|
324 | nrst , // I, n reset |
---|
325 | cc_start , // I, start pulse |
---|
326 | rate , // I, code rate, 0 = 1/2, 1 = 2/3, 2 = 3/4 |
---|
327 | vin , // I, valid in |
---|
328 | din , // I, parallel data input [3:0] |
---|
329 | vout , // O, encoded data out valid |
---|
330 | dout , // O, Parallel data output [7:0] |
---|
331 | mask // O, mask |
---|
332 | ) ; |
---|
333 | |
---|
334 | input clk ; |
---|
335 | input ce ; |
---|
336 | input nrst ; |
---|
337 | input cc_start ; |
---|
338 | input [1:0] rate ; |
---|
339 | input vin ; |
---|
340 | input [3:0] din ; |
---|
341 | output vout ; |
---|
342 | output [7:0] dout ; |
---|
343 | output reg [7:0] mask ; |
---|
344 | |
---|
345 | //=========================================== |
---|
346 | //Internal signal |
---|
347 | //=========================================== |
---|
348 | wire [3:0] u ; |
---|
349 | wire [7:0] v ; |
---|
350 | |
---|
351 | reg s0 ; |
---|
352 | reg s1 ; |
---|
353 | reg s2 ; |
---|
354 | reg s3 ; |
---|
355 | reg s4 ; |
---|
356 | reg s5 ; |
---|
357 | |
---|
358 | wire s0_next ; |
---|
359 | wire s1_next ; |
---|
360 | wire s2_next ; |
---|
361 | wire s3_next ; |
---|
362 | wire s4_next ; |
---|
363 | wire s5_next ; |
---|
364 | |
---|
365 | wire [3:0] A ; |
---|
366 | wire [3:0] B ; |
---|
367 | |
---|
368 | reg [1:0] cnt ; |
---|
369 | |
---|
370 | //=========================================== |
---|
371 | // Main body of code |
---|
372 | //=========================================== |
---|
373 | assign vout = vin ; |
---|
374 | assign dout = v ; |
---|
375 | |
---|
376 | assign A[3] = u[3] ^ s1 ^ s2 ^ s4 ^ s5 ; |
---|
377 | assign B[3] = u[3] ^ s0 ^ s1 ^ s2 ^ s5 ; |
---|
378 | |
---|
379 | assign A[2] = (u[2] ^ s0 ^ s1 ^ s3 ^ s4) ; |
---|
380 | assign B[2] = (u[2] ^ u[3] ^ s0 ^ s1 ^ s4) ; |
---|
381 | |
---|
382 | assign A[1] = (u[1] ^ u[3] ^ s0 ^ s2 ^ s3) ; |
---|
383 | assign B[1] = (u[1] ^ u[2] ^ u[3] ^ s0 ^ s3) ; |
---|
384 | |
---|
385 | assign A[0] = (u[0] ^ u[2] ^ u[3] ^ s1 ^ s2) ; |
---|
386 | assign B[0] = (u[0] ^ u[1] ^ u[2] ^ u[3] ^ s2) ; |
---|
387 | |
---|
388 | assign u = din ; |
---|
389 | assign v = {A[3], B[3], A[2], B[2], A[1], B[1], A[0], B[0]} ; |
---|
390 | |
---|
391 | assign s0_next = u[0] ; |
---|
392 | assign s1_next = u[1] ; |
---|
393 | assign s2_next = u[2] ; |
---|
394 | assign s3_next = u[3] ; |
---|
395 | assign s4_next = s0 ; |
---|
396 | assign s5_next = s1 ; |
---|
397 | |
---|
398 | always @ (posedge clk or negedge nrst) |
---|
399 | if (~nrst) |
---|
400 | begin |
---|
401 | s0 <= 1'b0 ; |
---|
402 | s1 <= 1'b0 ; |
---|
403 | s2 <= 1'b0 ; |
---|
404 | s3 <= 1'b0 ; |
---|
405 | s4 <= 1'b0 ; |
---|
406 | s5 <= 1'b0 ; |
---|
407 | end |
---|
408 | else if (ce) |
---|
409 | begin |
---|
410 | if (cc_start) |
---|
411 | begin |
---|
412 | s0 <= 1'b0 ; |
---|
413 | s1 <= 1'b0 ; |
---|
414 | s2 <= 1'b0 ; |
---|
415 | s3 <= 1'b0 ; |
---|
416 | s4 <= 1'b0 ; |
---|
417 | s5 <= 1'b0 ; |
---|
418 | end |
---|
419 | else if (vin) |
---|
420 | begin |
---|
421 | s0 <= s0_next ; |
---|
422 | s1 <= s1_next ; |
---|
423 | s2 <= s2_next ; |
---|
424 | s3 <= s3_next ; |
---|
425 | s4 <= s4_next ; |
---|
426 | s5 <= s5_next ; |
---|
427 | end |
---|
428 | end |
---|
429 | |
---|
430 | always @ (posedge clk or negedge nrst) |
---|
431 | if (~nrst) |
---|
432 | cnt <= 0 ; |
---|
433 | else if (ce) |
---|
434 | begin |
---|
435 | if (cc_start) |
---|
436 | cnt <= 0 ; |
---|
437 | else if (vin) |
---|
438 | begin |
---|
439 | if (cnt == 2) |
---|
440 | cnt <= 0 ; |
---|
441 | else |
---|
442 | cnt <= cnt +1 ; |
---|
443 | end |
---|
444 | end |
---|
445 | |
---|
446 | always @* |
---|
447 | begin |
---|
448 | mask = 8'd0 ; |
---|
449 | if (rate == 0) |
---|
450 | mask = 8'b1111_1111 ; |
---|
451 | else if (rate == 1) |
---|
452 | mask = 8'b1110_1110 ; |
---|
453 | else |
---|
454 | begin |
---|
455 | case(cnt) |
---|
456 | 0: mask = 8'b1110_0111 ; |
---|
457 | 1: mask = 8'b1001_1110 ; |
---|
458 | 2: mask = 8'b0111_1001 ; |
---|
459 | default: mask = 8'b1110_0111 ; |
---|
460 | endcase |
---|
461 | end |
---|
462 | end |
---|
463 | |
---|
464 | endmodule |
---|
465 | |
---|
466 | |
---|
467 | //************************************************************** |
---|
468 | // File: cc_puncture.v |
---|
469 | // Author: Yang Sun (ysun@rice.edu) |
---|
470 | // Created: $ 09/27/08 |
---|
471 | // Des: data puncture |
---|
472 | // |
---|
473 | // History: $ 09/27/08, created |
---|
474 | //************************************************************** |
---|
475 | module cc_puncture ( |
---|
476 | din , // I, data in |
---|
477 | mask , // I, data in mask |
---|
478 | dout , // O, data out |
---|
479 | ndout // O, number of output bits |
---|
480 | ) ; |
---|
481 | |
---|
482 | input [7:0] din ; |
---|
483 | input [7:0] mask ; |
---|
484 | |
---|
485 | output reg [7:0] dout ; |
---|
486 | output reg [3:0] ndout ; |
---|
487 | |
---|
488 | //=========================================== |
---|
489 | //Internal signal |
---|
490 | //=========================================== |
---|
491 | |
---|
492 | |
---|
493 | //=========================================== |
---|
494 | // Main RTL |
---|
495 | //=========================================== |
---|
496 | always @* |
---|
497 | begin |
---|
498 | ndout = 8 ; |
---|
499 | dout = din ; |
---|
500 | |
---|
501 | case (mask) |
---|
502 | 8'b1111_1111: begin // rate 1/2 |
---|
503 | ndout = 8 ; |
---|
504 | dout = din ; |
---|
505 | end |
---|
506 | 8'b1110_1110: begin // rate 2/3 |
---|
507 | ndout = 6 ; |
---|
508 | dout = {din[7:5], din[3:1], 1'b0, 1'b0} ; |
---|
509 | end |
---|
510 | 8'b1110_0111: begin // rate 3/4 |
---|
511 | ndout = 6 ; |
---|
512 | dout = {din[7:5], din[2:0], 1'b0, 1'b0} ; |
---|
513 | end |
---|
514 | 8'b1001_1110: begin // rate 3/4 |
---|
515 | ndout = 5 ; |
---|
516 | dout = {din[7], din[4:1], 1'b0, 1'b0, 1'b0} ; |
---|
517 | end |
---|
518 | 8'b0111_1001: begin // rate 3/4 |
---|
519 | ndout = 5 ; |
---|
520 | dout = {din[6:3], din[0], 1'b0, 1'b0, 1'b0} ; |
---|
521 | end |
---|
522 | endcase |
---|
523 | end |
---|
524 | |
---|
525 | endmodule |
---|
526 | |
---|
527 | //********************************************************* |
---|
528 | // File: my_fifo_a.v |
---|
529 | // Author: Y. Sun |
---|
530 | // Des: Asnyc read FIFO |
---|
531 | //********************************************************* |
---|
532 | module fifo_async_rd ( |
---|
533 | clk , // I, clock |
---|
534 | ce , // I, clock en |
---|
535 | nrst , // I, async reset |
---|
536 | reset , // I, sync reset |
---|
537 | wdata , // I, write data |
---|
538 | wr , // I, write enable |
---|
539 | rd , // I, read enable |
---|
540 | rdata , // I, read data |
---|
541 | empty , // O, empty |
---|
542 | half_full , // O, half full |
---|
543 | full // O, full |
---|
544 | ) ; |
---|
545 | |
---|
546 | parameter WIDTH = 8 ; |
---|
547 | parameter DEPTH = 8 ; |
---|
548 | parameter ADDR_BITS = 3 ; |
---|
549 | |
---|
550 | input clk ; |
---|
551 | input ce ; |
---|
552 | input nrst ; |
---|
553 | input reset ; |
---|
554 | input [WIDTH-1:0] wdata ; |
---|
555 | input wr ; |
---|
556 | input rd ; |
---|
557 | output [WIDTH-1:0] rdata ; |
---|
558 | output empty ; |
---|
559 | output half_full ; |
---|
560 | output full ; |
---|
561 | |
---|
562 | |
---|
563 | //============================ |
---|
564 | // Internal signals |
---|
565 | //============================ |
---|
566 | reg [WIDTH-1:0] mem [DEPTH-1:0] ; |
---|
567 | reg [ADDR_BITS:0] cnt ; |
---|
568 | reg [ADDR_BITS-1:0] waddr ; |
---|
569 | reg [ADDR_BITS-1:0] raddr ; |
---|
570 | |
---|
571 | //============================ |
---|
572 | // Main RTL Code |
---|
573 | //============================ |
---|
574 | assign empty = cnt == 0 ; |
---|
575 | assign full = cnt == DEPTH ; |
---|
576 | assign half_full = cnt >= DEPTH/2 ; |
---|
577 | |
---|
578 | |
---|
579 | always @ (posedge clk or negedge nrst) |
---|
580 | if(~nrst) |
---|
581 | cnt <= 0 ; |
---|
582 | else if(ce) |
---|
583 | begin |
---|
584 | if (reset) |
---|
585 | cnt <= 0 ; |
---|
586 | else if (wr & ~rd) |
---|
587 | cnt <= cnt +1 ; |
---|
588 | else if (rd & ~wr) |
---|
589 | cnt <= cnt -1 ; |
---|
590 | end |
---|
591 | |
---|
592 | always @ (posedge clk or negedge nrst) |
---|
593 | if(~nrst) |
---|
594 | waddr <= 0 ; |
---|
595 | else if(ce) |
---|
596 | begin |
---|
597 | if (reset) |
---|
598 | waddr <= 0 ; |
---|
599 | else if (wr) |
---|
600 | waddr <= waddr == DEPTH -1 ? 0 : waddr +1 ; |
---|
601 | end |
---|
602 | |
---|
603 | always @ (posedge clk or negedge nrst) |
---|
604 | if(~nrst) |
---|
605 | raddr <= 0 ; |
---|
606 | else if(ce) |
---|
607 | begin |
---|
608 | if (reset) |
---|
609 | raddr <= 0 ; |
---|
610 | else if (rd) |
---|
611 | raddr <= raddr == DEPTH -1 ? 0 : raddr +1 ; |
---|
612 | end |
---|
613 | |
---|
614 | always @ (posedge clk) |
---|
615 | if(ce) |
---|
616 | begin |
---|
617 | if (wr) |
---|
618 | mem [waddr] <= wdata ; |
---|
619 | end |
---|
620 | |
---|
621 | assign rdata = mem [raddr] ; |
---|
622 | |
---|
623 | endmodule |
---|
624 | |
---|
625 | //******************************************************************************** |
---|
626 | // File: sfifo_8to4 |
---|
627 | // Author: Yang Sun (ysun@rice.edu) |
---|
628 | // Birth: $ 11/24/07 |
---|
629 | // Des: Small size serial fifo |
---|
630 | // History: $ 11/24/07, Created |
---|
631 | // $ 11/26/07, Modify input format |
---|
632 | //******************************************************************************** |
---|
633 | module sfifo_8to4 ( |
---|
634 | clk , // clock |
---|
635 | ce , // clock enable |
---|
636 | nrst , // asyn reset |
---|
637 | reset , // sync reset |
---|
638 | din , // data input |
---|
639 | dout , // data output |
---|
640 | rd , // read |
---|
641 | wr , // write |
---|
642 | full , // fifo full |
---|
643 | empty , // fifo empty |
---|
644 | nsin , // num of shift in (bits), could be 4, 6 or 8 |
---|
645 | nsout // num of shift out (bits), could be 2 or 4. |
---|
646 | ) ; |
---|
647 | |
---|
648 | input clk ; |
---|
649 | input ce ; |
---|
650 | input nrst ; |
---|
651 | input reset ; |
---|
652 | input [7:0] din ; |
---|
653 | output [3:0] dout ; |
---|
654 | input rd ; |
---|
655 | input wr ; |
---|
656 | output full ; |
---|
657 | output empty ; |
---|
658 | input [3:0] nsin ; |
---|
659 | input [3:0] nsout ; |
---|
660 | |
---|
661 | //========================= |
---|
662 | // Internal signal |
---|
663 | //========================= |
---|
664 | reg [15:0] buffer ; |
---|
665 | reg [4:0] cnt ; |
---|
666 | wire [19:0] shift_out ; |
---|
667 | wire [23:0] shift_in ; |
---|
668 | wire [4:0] space_left ; |
---|
669 | |
---|
670 | //========================= |
---|
671 | // Main RTL |
---|
672 | //========================= |
---|
673 | assign full = (cnt + nsin) > 16 ; |
---|
674 | assign empty = cnt < nsout ; |
---|
675 | |
---|
676 | always @ (posedge clk or negedge nrst) |
---|
677 | if (~nrst) |
---|
678 | cnt <= 0 ; |
---|
679 | else if (ce) |
---|
680 | begin |
---|
681 | if (reset) |
---|
682 | cnt <= 0 ; |
---|
683 | else |
---|
684 | begin |
---|
685 | if (wr & rd) |
---|
686 | cnt <= cnt +nsin -nsout ; |
---|
687 | if (wr & ~rd) |
---|
688 | cnt <= cnt +nsin ; |
---|
689 | if (~wr & rd) |
---|
690 | cnt <= cnt -nsout ; |
---|
691 | end |
---|
692 | end |
---|
693 | |
---|
694 | assign shift_out = {4'h0, buffer} << nsout ; |
---|
695 | assign dout = shift_out [19:16] ; |
---|
696 | |
---|
697 | assign space_left = rd ? 16 -cnt + nsout : 16 -cnt ; |
---|
698 | assign shift_in = {16'h0, din} << space_left ; |
---|
699 | |
---|
700 | always @ (posedge clk or negedge nrst) |
---|
701 | if (~nrst) |
---|
702 | buffer <= 0 ; |
---|
703 | else if (ce) |
---|
704 | begin |
---|
705 | if (reset) |
---|
706 | buffer <= 0 ; |
---|
707 | else |
---|
708 | begin |
---|
709 | if (wr & rd) |
---|
710 | buffer <= shift_out [15:0] | shift_in [23:8] ; |
---|
711 | if (wr & ~rd) |
---|
712 | buffer <= buffer | shift_in [23:8] ; |
---|
713 | if (~wr & rd) |
---|
714 | buffer <= shift_out [15:0] ; |
---|
715 | end |
---|
716 | end |
---|
717 | |
---|
718 | endmodule |
---|
719 | |
---|
720 | //******************************************************************************** |
---|
721 | // File: sfifo_8to8 |
---|
722 | // Author: Yang Sun (ysun@rice.edu) |
---|
723 | // Des: Small size serial fifo, n bit in, 8 bit out |
---|
724 | //******************************************************************************** |
---|
725 | module sfifo_nto8 ( |
---|
726 | clk , // clock |
---|
727 | ce , // clock enable |
---|
728 | nrst , // asyn reset |
---|
729 | reset , // sync reset |
---|
730 | din , // data input |
---|
731 | dout , // data output |
---|
732 | rd , // read |
---|
733 | wr , // write |
---|
734 | full , // fifo full |
---|
735 | empty , // fifo empty |
---|
736 | nsin , // num of shift in (bits) |
---|
737 | nsout // num of shift out (bits) |
---|
738 | ) ; |
---|
739 | |
---|
740 | input clk ; |
---|
741 | input ce ; |
---|
742 | input nrst ; |
---|
743 | input reset ; |
---|
744 | input [7:0] din ; |
---|
745 | output [7:0] dout ; |
---|
746 | input rd ; |
---|
747 | input wr ; |
---|
748 | output full ; |
---|
749 | output empty ; |
---|
750 | input [3:0] nsin ; |
---|
751 | input [3:0] nsout ; |
---|
752 | |
---|
753 | //========================================= |
---|
754 | // Internal signal |
---|
755 | //========================================= |
---|
756 | reg [23:0] buffer ; // 24-bit buffer |
---|
757 | reg [5:0] cnt ; // counter to record num of bits loaded into buffer |
---|
758 | wire [31:0] shift_out ; |
---|
759 | wire [31:0] shift_in ; |
---|
760 | wire [5:0] space_left ; |
---|
761 | |
---|
762 | //========================================= |
---|
763 | // Main RTL |
---|
764 | //========================================= |
---|
765 | assign dout = shift_out [31:24] ; |
---|
766 | assign full = (cnt + nsin) > 24 ; |
---|
767 | assign empty = cnt < nsout ; |
---|
768 | |
---|
769 | always @ (posedge clk or negedge nrst) |
---|
770 | if (~nrst) |
---|
771 | cnt <= 0 ; |
---|
772 | else if (ce) |
---|
773 | begin |
---|
774 | if (reset) |
---|
775 | cnt <= 0 ; |
---|
776 | else |
---|
777 | begin |
---|
778 | if (wr & rd) |
---|
779 | cnt <= cnt + nsin - nsout ; |
---|
780 | if (wr & ~rd) |
---|
781 | cnt <= cnt + nsin ; |
---|
782 | if (~wr & rd) |
---|
783 | cnt <= cnt - nsout ; |
---|
784 | end |
---|
785 | end |
---|
786 | |
---|
787 | assign shift_out = {8'h0, buffer} << nsout ; |
---|
788 | assign space_left = rd ? 24 -cnt + nsout : 24 -cnt ; |
---|
789 | assign shift_in = {24'h0, din} << space_left ; |
---|
790 | |
---|
791 | always @ (posedge clk or negedge nrst) |
---|
792 | if (~nrst) |
---|
793 | buffer <= 0 ; |
---|
794 | else if (ce) |
---|
795 | begin |
---|
796 | if (reset) |
---|
797 | buffer <= 0 ; |
---|
798 | else |
---|
799 | begin |
---|
800 | if (wr & rd) |
---|
801 | buffer <= shift_out [23:0] | shift_in [31:8] ; |
---|
802 | if (wr & ~rd) |
---|
803 | buffer <= buffer | shift_in [31:8] ; |
---|
804 | if (~wr & rd) |
---|
805 | buffer <= shift_out [23:0] ; |
---|
806 | end |
---|
807 | end |
---|
808 | |
---|
809 | endmodule |
---|