OpenCores
URL https://opencores.org/ocsvn/xge_mac/xge_mac/trunk

Subversion Repositories xge_mac

[/] [xge_mac/] [tags/] [initial/] [rtl/] [verilog/] [tx_dequeue.v] - Blame information for rev 7

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 antanguay
//////////////////////////////////////////////////////////////////////
2
////                                                              ////
3
////  File name "tx_dequeue.v"                                    ////
4
////                                                              ////
5
////  This file is part of the "10GE MAC" project                 ////
6
////  http://www.opencores.org/cores/xge_mac/                     ////
7
////                                                              ////
8
////  Author(s):                                                  ////
9
////      - A. Tanguay (antanguay@opencores.org)                  ////
10
////                                                              ////
11
//////////////////////////////////////////////////////////////////////
12
////                                                              ////
13
//// Copyright (C) 2008 AUTHORS. All rights reserved.             ////
14
////                                                              ////
15
//// This source file may be used and distributed without         ////
16
//// restriction provided that this copyright statement is not    ////
17
//// removed from the file and that any derivative work contains  ////
18
//// the original copyright notice and the associated disclaimer. ////
19
////                                                              ////
20
//// This source file is free software; you can redistribute it   ////
21
//// and/or modify it under the terms of the GNU Lesser General   ////
22
//// Public License as published by the Free Software Foundation; ////
23
//// either version 2.1 of the License, or (at your option) any   ////
24
//// later version.                                               ////
25
////                                                              ////
26
//// This source is distributed in the hope that it will be       ////
27
//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
28
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
29
//// PURPOSE.  See the GNU Lesser General Public License for more ////
30
//// details.                                                     ////
31
////                                                              ////
32
//// You should have received a copy of the GNU Lesser General    ////
33
//// Public License along with this source; if not, download it   ////
34
//// from http://www.opencores.org/lgpl.shtml                     ////
35
////                                                              ////
36
//////////////////////////////////////////////////////////////////////
37
 
38
 
39
`include "defines.v"
40
 
41
module tx_dequeue(/*AUTOARG*/
42
  // Outputs
43
  txdfifo_ren, txhfifo_ren, txhfifo_wdata, txhfifo_wstatus,
44
  txhfifo_wen, xgmii_txd, xgmii_txc, status_txdfifo_udflow_tog,
45
  // Inputs
46
  clk_xgmii_tx, reset_xgmii_tx_n, ctrl_tx_enable_ctx,
47
  status_local_fault_ctx, status_remote_fault_ctx, txdfifo_rdata,
48
  txdfifo_rstatus, txdfifo_rempty, txdfifo_ralmost_empty,
49
  txhfifo_rdata, txhfifo_rstatus, txhfifo_rempty,
50
  txhfifo_ralmost_empty, txhfifo_wfull, txhfifo_walmost_full
51
  );
52
`include "CRC32_D64.v"
53
`include "CRC32_D8.v"
54
`include "utils.v"
55
 
56
input         clk_xgmii_tx;
57
input         reset_xgmii_tx_n;
58
 
59
input         ctrl_tx_enable_ctx;
60
 
61
input         status_local_fault_ctx;
62
input         status_remote_fault_ctx;
63
 
64
input  [63:0] txdfifo_rdata;
65
input  [7:0]  txdfifo_rstatus;
66
input         txdfifo_rempty;
67
input         txdfifo_ralmost_empty;
68
 
69
input  [63:0] txhfifo_rdata;
70
input  [7:0]  txhfifo_rstatus;
71
input         txhfifo_rempty;
72
input         txhfifo_ralmost_empty;
73
 
74
input         txhfifo_wfull;
75
input         txhfifo_walmost_full;
76
 
77
output        txdfifo_ren;
78
 
79
output        txhfifo_ren;
80
 
81
output [63:0] txhfifo_wdata;
82
output [7:0]  txhfifo_wstatus;
83
output        txhfifo_wen;
84
 
85
output [63:0] xgmii_txd;
86
output [7:0]  xgmii_txc;
87
 
88
output        status_txdfifo_udflow_tog;
89
 
90
 
91
 
92
 
93
/*AUTOREG*/
94
// Beginning of automatic regs (for this module's undeclared outputs)
95
reg                     status_txdfifo_udflow_tog;
96
reg                     txdfifo_ren;
97
reg                     txhfifo_ren;
98
reg [63:0]              txhfifo_wdata;
99
reg                     txhfifo_wen;
100
reg [7:0]               txhfifo_wstatus;
101
reg [7:0]               xgmii_txc;
102
reg [63:0]              xgmii_txd;
103
// End of automatics
104
 
105
/*AUTOWIRE*/
106
// Beginning of automatic wires (for undeclared instantiated-module outputs)
107
// End of automatics
108
 
109
 
110
reg   [63:0]    xgxs_txd;
111
reg   [7:0]     xgxs_txc;
112
 
113
reg   [63:0]    next_xgxs_txd;
114
reg   [7:0]     next_xgxs_txc;
115
 
116
reg   [2:0]     curr_state;
117
reg   [2:0]     next_state;
118
 
119
reg   [1:0]     curr_state_rd;
120
reg   [1:0]     next_state_rd;
121
 
122
reg             start_on_lane0;
123
reg             next_start_on_lane0;
124
 
125
reg   [2:0]     ifg_deficit;
126
reg   [2:0]     next_ifg_deficit;
127
 
128
reg             ifg_4b_add;
129
reg             next_ifg_4b_add;
130
 
131
reg             ifg_8b_add;
132
reg             next_ifg_8b_add;
133
 
134
reg             ifg_8b2_add;
135
reg             next_ifg_8b2_add;
136
 
137
reg   [63:32]   xgxs_txd_barrel;
138
reg   [7:4]     xgxs_txc_barrel;
139
 
140
reg   [63:0]    txhfifo_rdata_d1;
141
 
142
reg             txdfifo_ralmost_empty_d1;
143
reg             txdfifo_ralmost_empty_d2;
144
 
145
reg   [13:0]    byte_cnt;
146
 
147
reg   [31:0]    crc32_d64;
148
reg   [31:0]    crc32_d8;
149
reg   [31:0]    crc32_tx;
150
 
151
reg   [63:0]    shift_crc_data;
152
reg   [7:0]     shift_crc_eop;
153
reg   [2:0]     shift_crc_cnt;
154
 
155
reg   [31:0]    crc_data;
156
 
157
reg             frame_available;
158
reg             next_frame_available;
159
 
160
reg   [63:0]    next_txhfifo_wdata;
161
reg   [7:0]     next_txhfifo_wstatus;
162
reg             next_txhfifo_wen;
163
 
164
parameter [2:0]
165
             SM_IDLE      = 3'd0,
166
             SM_PREAMBLE  = 3'd1,
167
             SM_TX        = 3'd2,
168
             SM_EOP       = 3'd3,
169
             SM_TERM      = 3'd4,
170
             SM_TERM_FAIL = 3'd5,
171
             SM_IFG       = 3'd6;
172
 
173
parameter [1:0]
174
             SM_RD_IDLE = 2'd0,
175
             SM_RD_EQ   = 2'd1,
176
             SM_RD_PAD  = 2'd2;
177
 
178
 
179
//---
180
// RC layer
181
 
182
always @(posedge clk_xgmii_tx or negedge reset_xgmii_tx_n) begin
183
 
184
    if (reset_xgmii_tx_n == 1'b0) begin
185
 
186
        xgmii_txd <= {8{`IDLE}};
187
        xgmii_txc <= 8'hff;
188
 
189
    end
190
    else begin
191
 
192
 
193
        //---
194
        // RC Layer, insert local or remote fault messages based on status
195
        // of fault state-machine
196
 
197
        if (status_local_fault_ctx) begin
198
 
199
            // If local fault detected, send remote fault message to
200
            // link partner
201
 
202
            xgmii_txd <= {`REMOTE_FAULT, 8'h0, 8'h0, `SEQUENCE,
203
                          `REMOTE_FAULT, 8'h0, 8'h0, `SEQUENCE};
204
            xgmii_txc <= {4'b0001, 4'b0001};
205
        end
206
        else if (status_remote_fault_ctx) begin
207
 
208
            // If remote fault detected, inhibit transmission and send
209
            // idle codes
210
 
211
            xgmii_txd <= {8{`IDLE}};
212
            xgmii_txc <= 8'hff;
213
        end
214
        else begin
215
            xgmii_txd <= xgxs_txd;
216
            xgmii_txc <= xgxs_txc;
217
        end
218
    end
219
 
220
end
221
 
222
 
223
always @(posedge clk_xgmii_tx or negedge reset_xgmii_tx_n) begin
224
 
225
    if (reset_xgmii_tx_n == 1'b0) begin
226
 
227
        curr_state <= SM_IDLE;
228
 
229
        start_on_lane0 <= 1'b1;
230
        ifg_deficit <= 3'b0;
231
        ifg_4b_add <= 1'b0;
232
        ifg_8b_add <= 1'b0;
233
        ifg_8b2_add <= 1'b0;
234
 
235
        txhfifo_rdata_d1 <= 64'b0;
236
 
237
        xgxs_txd_barrel <= {4{`IDLE}};
238
        xgxs_txc_barrel <= 4'hf;
239
 
240
        txdfifo_ralmost_empty_d1 <= 1'b1;
241
        txdfifo_ralmost_empty_d2 <= 1'b1;
242
 
243
        frame_available <= 1'b0;
244
 
245
        xgxs_txd <= {8{`IDLE}};
246
        xgxs_txc <= 8'hff;
247
 
248
        status_txdfifo_udflow_tog <= 1'b0;
249
 
250
    end
251
    else begin
252
 
253
        curr_state <= next_state;
254
 
255
        start_on_lane0 <= next_start_on_lane0;
256
        ifg_deficit <= next_ifg_deficit;
257
        ifg_4b_add <= next_ifg_4b_add;
258
        ifg_8b_add <= next_ifg_8b_add;
259
        ifg_8b2_add <= next_ifg_8b2_add;
260
 
261
        txhfifo_rdata_d1 <= txhfifo_rdata;
262
 
263
        xgxs_txd_barrel <= next_xgxs_txd[63:32];
264
        xgxs_txc_barrel <= next_xgxs_txc[7:4];
265
 
266
        txdfifo_ralmost_empty_d1 <= txdfifo_ralmost_empty;
267
        txdfifo_ralmost_empty_d2 <= txdfifo_ralmost_empty_d1;
268
 
269
        frame_available <= next_frame_available;
270
 
271
        //---
272
        // Barrel shifter. Previous stage always align packet with LANE0.
273
        // This stage allow us to shift packet to align with LANE4 if needed
274
        // for correct inter frame gap (IFG).
275
 
276
        if (next_start_on_lane0) begin
277
 
278
            xgxs_txd <= next_xgxs_txd;
279
            xgxs_txc <= next_xgxs_txc;
280
 
281
        end
282
        else begin
283
 
284
            xgxs_txd <= {next_xgxs_txd[31:0], xgxs_txd_barrel};
285
            xgxs_txc <= {next_xgxs_txc[3:0], xgxs_txc_barrel};
286
 
287
        end
288
 
289
        //---
290
        // FIFO errors, used to generate interrupts.
291
 
292
        if (txdfifo_ren && txdfifo_rempty) begin
293
            status_txdfifo_udflow_tog <= ~status_txdfifo_udflow_tog;
294
        end
295
 
296
    end
297
 
298
end
299
 
300
always @(/*AS*/crc32_tx or ctrl_tx_enable_ctx or curr_state
301
         or frame_available or ifg_4b_add or ifg_8b2_add or ifg_8b_add
302
         or ifg_deficit or start_on_lane0 or status_local_fault_ctx
303
         or txhfifo_ralmost_empty or txhfifo_rdata_d1
304
         or txhfifo_rempty or txhfifo_rstatus) begin
305
 
306
    next_state = curr_state;
307
 
308
    next_start_on_lane0 = start_on_lane0;
309
    next_ifg_deficit = ifg_deficit;
310
    next_ifg_4b_add = ifg_4b_add;
311
    next_ifg_8b_add = ifg_8b_add;
312
    next_ifg_8b2_add = ifg_8b2_add;
313
 
314
    next_xgxs_txd = {8{`IDLE}};
315
    next_xgxs_txc = 8'hff;
316
 
317
    txhfifo_ren = 1'b0;
318
 
319
    next_frame_available = frame_available;
320
 
321
    case (curr_state)
322
 
323
        SM_IDLE:
324
          begin
325
 
326
              // Wait for frame to be available. There should be a least N bytes in the
327
              // data fifo or a crc in the control fifo. The N bytes in the data fifo
328
              // give time to the enqueue engine to calculate crc and write it to the
329
              // control fifo. If crc is already in control fifo we can start transmitting
330
              // with no concern. Transmission is inhibited if local or remote faults
331
              // are detected.
332
 
333
              if (ctrl_tx_enable_ctx && frame_available &&
334
                  !status_local_fault_ctx && !status_local_fault_ctx) begin
335
 
336
                  txhfifo_ren = 1'b1;
337
                  next_state = SM_PREAMBLE;
338
 
339
              end
340
              else begin
341
 
342
                  next_frame_available = !txhfifo_ralmost_empty;
343
                  next_ifg_4b_add = 1'b0;
344
 
345
              end
346
 
347
          end
348
 
349
        SM_PREAMBLE:
350
         begin
351
 
352
             txhfifo_ren = 1'b1;
353
 
354
 
355
             // On reading SOP from fifo, send SFD and preamble characters
356
 
357
             if (txhfifo_rstatus == `TXSTATUS_SOP) begin
358
 
359
                 next_xgxs_txd = {`SFD, {6{`PREAMBLE}}, `START};
360
                 next_xgxs_txc = 8'h01;
361
 
362
             end
363
 
364
 
365
             // Depending on deficit idle count calculations, add 4 bytes
366
             // or IFG or not. This will determine on which lane start the
367
             // next frame.
368
 
369
             if (ifg_4b_add) begin
370
                 next_start_on_lane0 = 1'b0;
371
             end
372
             else begin
373
                 next_start_on_lane0 = 1'b1;
374
             end
375
 
376
             next_state = SM_TX;
377
 
378
          end
379
 
380
        SM_TX:
381
          begin
382
 
383
              next_xgxs_txd = txhfifo_rdata_d1;
384
              next_xgxs_txc = 8'h00;
385
 
386
              txhfifo_ren = 1'b1;
387
 
388
 
389
              // Wait for EOP indication to be read from the fifo, then
390
              // transition to next state.
391
 
392
              if (txhfifo_rstatus == `TXSTATUS_EOP0 ||
393
                  txhfifo_rstatus == `TXSTATUS_EOP1 ||
394
                  txhfifo_rstatus == `TXSTATUS_EOP2 ||
395
                  txhfifo_rstatus == `TXSTATUS_EOP3 ||
396
                  txhfifo_rstatus == `TXSTATUS_EOP4 ||
397
                  txhfifo_rstatus == `TXSTATUS_EOP5 ||
398
                  txhfifo_rstatus == `TXSTATUS_EOP6 ||
399
                  txhfifo_rstatus == `TXSTATUS_EOP7) begin
400
 
401
                  txhfifo_ren = 1'b0;
402
                  next_frame_available = !txhfifo_ralmost_empty;
403
                  next_state = SM_EOP;
404
              end
405
              else if (txhfifo_rempty) begin
406
 
407
                  // Failure condition, we did not see EOP and there
408
                  // is no more data in fifo, force end of packet transmit.
409
 
410
                  next_state = SM_TERM_FAIL;
411
 
412
              end
413
 
414
          end
415
 
416
        SM_EOP:
417
          begin
418
 
419
              // Insert TERMINATE character in correct lane depending on position
420
              // of EOP read from fifo. Also insert CRC read from control fifo.
421
 
422
              if (txhfifo_rstatus[0]) begin
423
                  next_xgxs_txd = {{2{`IDLE}}, `TERMINATE,
424
                                   crc32_tx[31:0], txhfifo_rdata_d1[7:0]};
425
                  next_xgxs_txc = 8'b11100000;
426
              end
427
 
428
              if (txhfifo_rstatus[1]) begin
429
                  next_xgxs_txd = {`IDLE, `TERMINATE,
430
                                   crc32_tx[31:0], txhfifo_rdata_d1[15:0]};
431
                  next_xgxs_txc = 8'b11000000;
432
              end
433
 
434
              if (txhfifo_rstatus[2]) begin
435
                  next_xgxs_txd = {`TERMINATE, crc32_tx[31:0], txhfifo_rdata_d1[23:0]};
436
                  next_xgxs_txc = 8'b10000000;
437
              end
438
 
439
              if (txhfifo_rstatus[3]) begin
440
                  next_xgxs_txd = {crc32_tx[31:0], txhfifo_rdata_d1[31:0]};
441
                  next_xgxs_txc = 8'b00000000;
442
              end
443
 
444
              if (txhfifo_rstatus[4]) begin
445
                  next_xgxs_txd = {crc32_tx[23:0], txhfifo_rdata_d1[39:0]};
446
                  next_xgxs_txc = 8'b00000000;
447
              end
448
 
449
              if (txhfifo_rstatus[5]) begin
450
                  next_xgxs_txd = {crc32_tx[15:0], txhfifo_rdata_d1[47:0]};
451
                  next_xgxs_txc = 8'b00000000;
452
              end
453
 
454
              if (txhfifo_rstatus[6]) begin
455
                  next_xgxs_txd = {crc32_tx[7:0], txhfifo_rdata_d1[55:0]};
456
                  next_xgxs_txc = 8'b00000000;
457
              end
458
 
459
              if (txhfifo_rstatus[7]) begin
460
                  next_xgxs_txd = {txhfifo_rdata_d1[63:0]};
461
                  next_xgxs_txc = 8'b00000000;
462
              end
463
 
464
              if (!frame_available) begin
465
 
466
                  // If there is not another frame ready to be transmitted, interface
467
                  // will go idle and idle deficit idle count calculation is irrelevant.
468
                  // Set deficit to 0.
469
 
470
                  next_ifg_deficit = 3'b0;
471
 
472
              end
473
              else begin
474
 
475
                  // Idle deficit count calculated based on number of "wasted" bytes
476
                  // between TERMINATE and alignment of next frame in LANE0.
477
 
478
                  next_ifg_deficit = ifg_deficit +
479
                                     {2'b0, txhfifo_rstatus[0] | txhfifo_rstatus[4]} +
480
                                     {1'b0, txhfifo_rstatus[1] | txhfifo_rstatus[5], 1'b0} +
481
                                     {1'b0, txhfifo_rstatus[2] | txhfifo_rstatus[6],
482
                                      txhfifo_rstatus[2] | txhfifo_rstatus[6]};
483
              end
484
 
485
              // IFG corrections based on deficit count and previous starting lane
486
              // Calculated based on following table:
487
              //
488
              //                 DIC=0          DIC=1          DIC=2          DIC=3
489
              //              -------------  -------------  -------------  -------------
490
              // PktLen       IFG      Next  IFG      Next  IFG      Next  IFG      Next
491
              // Modulus      Length   DIC   Length   DIC   Length   DIC   Length   DIC
492
              // -----------------------------------------------------------------------
493
              //    0           12      0      12      1      12      2      12      3
494
              //    1           11      1      11      2      11      3      15      0
495
              //    2           10      2      10      3      14      0      14      1
496
              //    3            9      3      13      0      13      1      13      2
497
              //
498
              //
499
              // In logic it translates into adding 4, 8, or 12 bytes of IFG relative
500
              // to LANE0.
501
              //   IFG and Add columns assume no deficit applied
502
              //   IFG+DIC and Add+DIC assume deficit must be applied
503
              //
504
              //                        Start lane 0       Start lane 4 
505
              // EOP Pads IFG  IFG+DIC  Add   Add+DIC      Add    Add IFG
506
              // 0   3    11   15        8     12           12     16
507
              // 1   2    10   14        8     12           12     16
508
              // 2   1    9    13        8     12           12     16
509
              // 3   8    12   12        4     4            8      8
510
              // 4   7    11   15        4     8            8      12
511
              // 5   6    10   14        4     8            8      12
512
              // 6   5    9    13        4     8            8      12
513
              // 7   4    12   12        8     8            12     12
514
 
515
              if (!frame_available) begin
516
 
517
                  // If there is not another frame ready to be transmitted, interface
518
                  // will go idle and idle deficit idle count calculation is irrelevant.
519
 
520
                  next_ifg_4b_add = 1'b0;
521
                  next_ifg_8b_add = 1'b0;
522
                  next_ifg_8b2_add = 1'b0;
523
 
524
              end
525
              else if (next_ifg_deficit[2] == ifg_deficit[2]) begin
526
 
527
                  // Add 4 bytes IFG
528
 
529
                  next_ifg_4b_add = (txhfifo_rstatus[0] & !start_on_lane0) |
530
                                    (txhfifo_rstatus[1] & !start_on_lane0) |
531
                                    (txhfifo_rstatus[2] & !start_on_lane0) |
532
                                    (txhfifo_rstatus[3] & start_on_lane0) |
533
                                    (txhfifo_rstatus[4] & start_on_lane0) |
534
                                    (txhfifo_rstatus[5] & start_on_lane0) |
535
                                    (txhfifo_rstatus[6] & start_on_lane0) |
536
                                    (txhfifo_rstatus[7] & !start_on_lane0);
537
 
538
                  // Add 8 bytes IFG
539
 
540
                  next_ifg_8b_add = (txhfifo_rstatus[0]) |
541
                                    (txhfifo_rstatus[1]) |
542
                                    (txhfifo_rstatus[2]) |
543
                                    (txhfifo_rstatus[3] & !start_on_lane0) |
544
                                    (txhfifo_rstatus[4] & !start_on_lane0) |
545
                                    (txhfifo_rstatus[5] & !start_on_lane0) |
546
                                    (txhfifo_rstatus[6] & !start_on_lane0) |
547
                                    (txhfifo_rstatus[7]);
548
 
549
                  // Add another 8 bytes IFG
550
 
551
                  next_ifg_8b2_add = 1'b0;
552
 
553
              end
554
              else begin
555
 
556
                  // Add 4 bytes IFG
557
 
558
                  next_ifg_4b_add = (txhfifo_rstatus[0] & start_on_lane0) |
559
                                    (txhfifo_rstatus[1] & start_on_lane0) |
560
                                    (txhfifo_rstatus[2] & start_on_lane0) |
561
                                    (txhfifo_rstatus[3] &  start_on_lane0) |
562
                                    (txhfifo_rstatus[4] & !start_on_lane0) |
563
                                    (txhfifo_rstatus[5] & !start_on_lane0) |
564
                                    (txhfifo_rstatus[6] & !start_on_lane0) |
565
                                    (txhfifo_rstatus[7] & !start_on_lane0);
566
 
567
                  // Add 8 bytes IFG
568
 
569
                  next_ifg_8b_add = (txhfifo_rstatus[0]) |
570
                                    (txhfifo_rstatus[1]) |
571
                                    (txhfifo_rstatus[2]) |
572
                                    (txhfifo_rstatus[3] & !start_on_lane0) |
573
                                    (txhfifo_rstatus[4]) |
574
                                    (txhfifo_rstatus[5]) |
575
                                    (txhfifo_rstatus[6]) |
576
                                    (txhfifo_rstatus[7]);
577
 
578
                  // Add another 8 bytes IFG
579
 
580
                  next_ifg_8b2_add = (txhfifo_rstatus[0] & !start_on_lane0) |
581
                                     (txhfifo_rstatus[1] & !start_on_lane0) |
582
                                     (txhfifo_rstatus[2] & !start_on_lane0);
583
 
584
              end
585
 
586
              if (|txhfifo_rstatus[2:0]) begin
587
 
588
                  if (frame_available) begin
589
 
590
                      // Next state depends on number of IFG bytes to be inserted.
591
                      // Skip idle state if needed.
592
 
593
                      if (next_ifg_8b2_add) begin
594
                          next_state = SM_IFG;
595
                      end
596
                      else if (next_ifg_8b_add) begin
597
                          next_state = SM_IDLE;
598
                      end
599
                      else begin
600
                          txhfifo_ren = 1'b1;
601
                          next_state = SM_PREAMBLE;
602
                      end
603
 
604
                  end
605
                  else begin
606
                      next_state = SM_IFG;
607
                  end
608
              end
609
 
610
              if (|txhfifo_rstatus[7:3]) begin
611
                  next_state = SM_TERM;
612
              end
613
 
614
          end
615
 
616
        SM_TERM:
617
          begin
618
 
619
              // Insert TERMINATE character in correct lane depending on position
620
              // of EOP read from fifo. Also insert CRC read from control fifo.
621
 
622
              if (txhfifo_rstatus[3]) begin
623
                  next_xgxs_txd = {{7{`IDLE}}, `TERMINATE};
624
                  next_xgxs_txc = 8'b11111111;
625
              end
626
 
627
              if (txhfifo_rstatus[4]) begin
628
                  next_xgxs_txd = {{6{`IDLE}}, `TERMINATE, crc32_tx[31:24]};
629
                  next_xgxs_txc = 8'b11111110;
630
              end
631
 
632
              if (txhfifo_rstatus[5]) begin
633
                  next_xgxs_txd = {{5{`IDLE}}, `TERMINATE, crc32_tx[31:16]};
634
                  next_xgxs_txc = 8'b11111100;
635
              end
636
 
637
              if (txhfifo_rstatus[6]) begin
638
                  next_xgxs_txd = {{4{`IDLE}}, `TERMINATE, crc32_tx[31:8]};
639
                  next_xgxs_txc = 8'b11111000;
640
              end
641
 
642
              if (txhfifo_rstatus[7]) begin
643
                  next_xgxs_txd = {{3{`IDLE}}, `TERMINATE, crc32_tx[31:0]};
644
                  next_xgxs_txc = 8'b11110000;
645
              end
646
 
647
              // Next state depends on number of IFG bytes to be inserted.
648
              // Skip idle state if needed.
649
 
650
              if (frame_available && !ifg_8b_add) begin
651
                  txhfifo_ren = 1'b1;
652
                  next_state = SM_PREAMBLE;
653
              end
654
              else if (frame_available) begin
655
                  next_state = SM_IDLE;
656
              end
657
              else begin
658
                  next_state = SM_IFG;
659
              end
660
 
661
          end
662
 
663
        SM_TERM_FAIL:
664
          begin
665
 
666
              next_xgxs_txd = {{7{`IDLE}}, `TERMINATE};
667
              next_xgxs_txc = 8'b11111111;
668
              next_state = SM_IFG;
669
 
670
          end
671
 
672
        SM_IFG:
673
          begin
674
 
675
              next_state = SM_IDLE;
676
 
677
          end
678
 
679
        default:
680
          begin
681
              next_state = SM_IDLE;
682
          end
683
 
684
    endcase
685
 
686
end
687
 
688
 
689
always @(/*AS*/crc32_d64 or txhfifo_wen or txhfifo_wstatus) begin
690
 
691
    if (txhfifo_wen && txhfifo_wstatus == `TXSTATUS_SOP) begin
692
        crc_data = 32'hffffffff;
693
    end
694
    else begin
695
        crc_data = crc32_d64;
696
    end
697
 
698
end
699
 
700
always @(/*AS*/byte_cnt or curr_state_rd or txdfifo_rdata
701
         or txdfifo_rempty or txdfifo_rstatus or txhfifo_ren
702
         or txhfifo_walmost_full) begin
703
 
704
    next_state_rd = curr_state_rd;
705
 
706
    next_txhfifo_wdata = txdfifo_rdata;
707
    next_txhfifo_wstatus = txdfifo_rstatus;
708
 
709
    txdfifo_ren = 1'b0;
710
    next_txhfifo_wen = 1'b0;
711
 
712
    case (curr_state_rd)
713
 
714
      SM_RD_IDLE: begin
715
 
716
          if (!txdfifo_rempty && !txhfifo_walmost_full) begin
717
 
718
              txdfifo_ren = 1'b1;
719
              next_txhfifo_wen = 1'b1;
720
              next_state_rd = SM_RD_EQ;
721
 
722
          end
723
 
724
      end
725
 
726
      SM_RD_EQ: begin
727
 
728
          if (!txhfifo_walmost_full || txhfifo_ren) begin
729
 
730
              txdfifo_ren = 1'b1;
731
              next_txhfifo_wen = 1'b1;
732
 
733
              if (txdfifo_rempty) begin
734
 
735
                  // If FIFO empty, do a last read and abort
736
 
737
                  next_state_rd = SM_RD_IDLE;
738
 
739
              end
740
              else if (txdfifo_rstatus == `TXSTATUS_EOP0 ||
741
                       txdfifo_rstatus == `TXSTATUS_EOP1 ||
742
                       txdfifo_rstatus == `TXSTATUS_EOP2 ||
743
                       txdfifo_rstatus == `TXSTATUS_EOP3 ||
744
                       txdfifo_rstatus == `TXSTATUS_EOP4 ||
745
                       txdfifo_rstatus == `TXSTATUS_EOP5 ||
746
                       txdfifo_rstatus == `TXSTATUS_EOP6 ||
747
                       txdfifo_rstatus == `TXSTATUS_EOP7) begin
748
 
749
                  if (byte_cnt < 14'd48) begin
750
 
751
                      next_txhfifo_wstatus = `TXSTATUS_NONE;
752
                      next_state_rd = SM_RD_PAD;
753
 
754
                  end
755
                  else if (byte_cnt == 14'd48 &&
756
                           (txdfifo_rstatus == `TXSTATUS_EOP0 ||
757
                            txdfifo_rstatus == `TXSTATUS_EOP1 ||
758
                            txdfifo_rstatus == `TXSTATUS_EOP2)) begin
759
 
760
                      // Pad up to LANE3, keep the other 4 bytes for crc that will
761
                      // be inserted by dequeue engine.
762
 
763
                      next_txhfifo_wstatus = `TXSTATUS_EOP3;
764
 
765
                      // Pad end bytes with zeros.
766
 
767
                      if (txdfifo_rstatus == `TXSTATUS_EOP0)
768
                        next_txhfifo_wdata[31:8] = 24'b0;
769
                      if (txdfifo_rstatus == `TXSTATUS_EOP1)
770
                        next_txhfifo_wdata[31:16] = 16'b0;
771
                      if (txdfifo_rstatus == `TXSTATUS_EOP2)
772
                        next_txhfifo_wdata[31:24] = 8'b0;
773
 
774
                      next_state_rd = SM_RD_IDLE;
775
 
776
                  end
777
                  else begin
778
 
779
                      next_state_rd = SM_RD_IDLE;
780
 
781
                  end
782
 
783
              end
784
 
785
          end
786
 
787
      end
788
 
789
      SM_RD_PAD: begin
790
 
791
          if (!txhfifo_walmost_full || txhfifo_ren) begin
792
 
793
              next_txhfifo_wdata = 64'b0;
794
              next_txhfifo_wstatus = `TXSTATUS_NONE;
795
              next_txhfifo_wen = 1'b1;
796
 
797
              if (byte_cnt == 14'd48) begin
798
 
799
 
800
                  // Pad up to LANE3, keep the other 4 bytes for crc that will
801
                  // be inserted by dequeue engine.
802
 
803
                  next_txhfifo_wstatus = `TXSTATUS_EOP3;
804
 
805
                  next_state_rd = SM_RD_IDLE;
806
 
807
              end
808
 
809
          end
810
 
811
      end
812
 
813
      default:
814
        begin
815
            next_state_rd = SM_RD_IDLE;
816
        end
817
 
818
    endcase
819
 
820
end
821
 
822
 
823
always @(posedge clk_xgmii_tx or negedge reset_xgmii_tx_n) begin
824
 
825
    if (reset_xgmii_tx_n == 1'b0) begin
826
 
827
        curr_state_rd <= SM_RD_IDLE;
828
 
829
        txhfifo_wdata <= 64'b0;
830
        txhfifo_wstatus <= 8'b0;
831
        txhfifo_wen <= 1'b0;
832
 
833
        byte_cnt <= 14'b0;
834
 
835
        shift_crc_data <= 64'b0;
836
        shift_crc_eop <= 8'b0;
837
        shift_crc_cnt <= 3'b0;
838
 
839
    end
840
    else begin
841
 
842
        curr_state_rd <= next_state_rd;
843
 
844
        txhfifo_wdata <= next_txhfifo_wdata;
845
        txhfifo_wstatus <= next_txhfifo_wstatus;
846
        txhfifo_wen <= next_txhfifo_wen;
847
 
848
        if (txhfifo_wen) begin
849
 
850
            if (txhfifo_wstatus == `TXSTATUS_SOP) begin
851
 
852
                byte_cnt <= 14'd8;
853
 
854
            end
855
            else begin
856
 
857
                byte_cnt <= byte_cnt + 14'd8;
858
 
859
            end
860
 
861
        end
862
 
863
        if (txhfifo_wen) begin
864
 
865
            crc32_d64 <= nextCRC32_D64(reverse_64b(txhfifo_wdata), crc_data);
866
 
867
        end
868
 
869
        if (txhfifo_wen &&
870
            (txhfifo_wstatus == `TXSTATUS_EOP0 ||
871
             txhfifo_wstatus == `TXSTATUS_EOP1 ||
872
             txhfifo_wstatus == `TXSTATUS_EOP2 ||
873
             txhfifo_wstatus == `TXSTATUS_EOP3 ||
874
             txhfifo_wstatus == `TXSTATUS_EOP4 ||
875
             txhfifo_wstatus == `TXSTATUS_EOP5 ||
876
             txhfifo_wstatus == `TXSTATUS_EOP6 ||
877
             txhfifo_wstatus == `TXSTATUS_EOP7)) begin
878
 
879
            // Last bytes calculated 8-bit at a time instead of 64-bit. Start
880
            // this process at the end of the frame.
881
 
882
            crc32_d8 <= crc32_d64;
883
 
884
            shift_crc_data <= txhfifo_wdata;
885
            shift_crc_eop <= txhfifo_wstatus;
886
            shift_crc_cnt <= 3'd7;
887
 
888
        end
889
        else if (shift_crc_eop != 8'b0) begin
890
 
891
            // Complete crc calculation 8-bit at a time until finished. This can
892
            // be 1 to 8 bytes long.
893
 
894
            crc32_d8 <= nextCRC32_D8(reverse_8b(shift_crc_data[7:0]), crc32_d8);
895
 
896
            shift_crc_data <= {8'b0, shift_crc_data[63:8]};
897
            shift_crc_eop <= {1'b0, shift_crc_eop[7:1]};
898
 
899
        end
900
 
901
        if (shift_crc_cnt == 3'b0) begin
902
            crc32_tx <= ~reverse_32b(crc32_d8);
903
        end
904
        else begin
905
            shift_crc_cnt <= shift_crc_cnt - 3'd1;
906
        end
907
 
908
    end
909
 
910
end
911
 
912
endmodule
913
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.