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

Subversion Repositories xge_ll_mac

[/] [xge_ll_mac/] [trunk/] [rtl/] [tx_dequeue.v] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 cleberCAG
//////////////////////////////////////////////////////////////////////
2
////                                                              ////
3
////  This file is part of the "10GE LL MAC" project              ////
4
////  http://www.opencores.org/cores/xge_ll_mac/                  ////
5
////                                                              ////
6
////  This project is derived from the "10GE MAC" project of      ////
7
////  A. Tanguay (antanguay@opencores.org) by Andreas Peters      ////
8
////  for his Diploma Thesis at the University of Heidelberg.     ////
9
////  The Thesis was supervised by Christian Leber                ////
10
////                                                              ////
11
////  Author(s):                                                  ////
12
////      - Andreas Peters                                        ////
13
////                                                              ////
14
//////////////////////////////////////////////////////////////////////
15
////                                                              ////
16
//// Copyright (C) 2008-2012 AUTHORS. All rights reserved.        ////
17
////                                                              ////
18
//// This source file may be used and distributed without         ////
19
//// restriction provided that this copyright statement is not    ////
20
//// removed from the file and that any derivative work contains  ////
21
//// the original copyright notice and the associated disclaimer. ////
22
////                                                              ////
23
//// This source file is free software; you can redistribute it   ////
24
//// and/or modify it under the terms of the GNU Lesser General   ////
25
//// Public License as published by the Free Software Foundation; ////
26
//// either version 2.1 of the License, or (at your option) any   ////
27
//// later version.                                               ////
28
////                                                              ////
29
//// This source is distributed in the hope that it will be       ////
30
//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
31
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
32
//// PURPOSE.  See the GNU Lesser General Public License for more ////
33
//// details.                                                     ////
34
////                                                              ////
35
//// You should have received a copy of the GNU Lesser General    ////
36
//// Public License along with this source; if not, download it   ////
37
//// from http://www.opencores.org/lgpl.shtml                     ////
38
////                                                              ////
39
//////////////////////////////////////////////////////////////////////
40
 
41
`include "oc_mac.h"
42
`include "oc_mac_crc_func.h"
43
 
44
module tx_dequeue(
45
  // Outputs
46
        input wire              clk,
47
        input wire              res_n,
48
        input wire [63:0]        txdfifo_rdata,
49
        input wire [7:0] txdfifo_rstatus,
50
 
51
        output reg [63:0]        xgmii_txd,
52
        output reg [7:0] xgmii_txc);
53
 
54
 
55
 
56
reg [63:0]       xgxs_txd;
57
reg [7:0]        xgxs_txc;
58
 
59
reg [63:0]       next_xgxs_txd;
60
reg [7:0]        next_xgxs_txc;
61
 
62
reg [2:0]        curr_state_enc;
63
reg [2:0]        next_state_enc;
64
 
65
reg [0:0] curr_state_pad;
66
reg[0:0]  next_state_pad;
67
 
68
 
69
 
70
 
71
reg [7:0]        eop;
72
reg [7:0]        next_eop;
73
 
74
 
75
 
76
reg [63:0]       txhfifo_wdata_d1;
77
 
78
reg [13:0]       byte_cnt;
79
 
80
reg [31:0]       crc32_d64;
81
reg [31:0]       crc32_tx;
82
 
83
reg [31:0]       crc_data;
84
 
85
 
86
 
87
 
88
reg [63:0]       next_txhfifo_wdata;
89
reg [7:0]        next_txhfifo_wstatus;
90
reg             next_txhfifo_wen;
91
 
92
 
93
reg [63:0]       txhfifo_wdata;
94
reg [7:0]        txhfifo_wstatus;
95
 
96
reg             status_local_fault_ctx; // for later implementations
97
reg             status_remote_fault_ctx;
98
 
99
 
100
 
101
parameter [2:0]
102
        //SM_IDLE      = 3'd0,
103
        SM_PREAMBLE  = 3'd0,
104
        SM_TX        = 3'd2,
105
        SM_EOP       = 3'd3,
106
        SM_TERM      = 3'd4,
107
        SM_TERM_FAIL = 3'd5;
108
 
109
parameter [0:0]
110
        SM_PAD_EQ    = 1'd0,
111
        SM_PAD_PAD   = 1'd1;
112
 
113
 
114
//---
115
// RC layer
116
 
117
`ifdef ASYNC_RES
118
always @(posedge clk or negedge res_n) `else
119
always @(posedge clk) `endif
120
begin
121
 
122
        if (res_n == 1'b0) begin
123
 
124
                xgmii_txd <= {8{`IDLE}};
125
                xgmii_txc <= 8'hff;
126
                status_remote_fault_ctx <= 1'b0;
127
                status_local_fault_ctx <= 1'b0;
128
 
129
                curr_state_enc <= SM_PREAMBLE;
130
 
131
 
132
                eop <= 8'b0;
133
 
134
                txhfifo_wdata_d1 <= 64'b0;
135
 
136
 
137
 
138
 
139
 
140
                xgxs_txd <= {8{`IDLE}};
141
                xgxs_txc <= 8'hff;
142
 
143
                curr_state_pad <= SM_PAD_EQ;
144
 
145
 
146
                txhfifo_wdata <= 64'b0;
147
                txhfifo_wstatus <= 8'b0;
148
 
149
                byte_cnt <= 14'b0;
150
 
151
 
152
        end
153
        else begin
154
                // no faults expected.
155
                status_remote_fault_ctx <= 1'b0;
156
                status_local_fault_ctx <= 1'b0;
157
                //---
158
                // RC Layer, insert local or remote fault messages based on status
159
                // of fault state-machine
160
 
161
                if (status_local_fault_ctx) begin
162
 
163
                // If local fault detected, send remote fault message to
164
                // link partner
165
                        xgmii_txd <= {`REMOTE_FAULT, 8'h0, 8'h0, `SEQUENCE,
166
                                        `REMOTE_FAULT, 8'h0, 8'h0, `SEQUENCE};
167
                        xgmii_txc <= {4'b0001, 4'b0001};
168
                end
169
                else if (status_remote_fault_ctx) begin
170
 
171
                // If remote fault detected, inhibit transmission and send
172
                // idle codes
173
                        xgmii_txd <= {8{`IDLE}};
174
                        xgmii_txc <= 8'hff;
175
                end
176
                else begin
177
                        xgmii_txd <= xgxs_txd;
178
                        xgmii_txc <= xgxs_txc;
179
                end
180
 
181
                curr_state_enc <= next_state_enc;
182
 
183
 
184
                eop <= next_eop;
185
 
186
                txhfifo_wdata_d1 <= txhfifo_wdata;
187
 
188
 
189
 
190
                xgxs_txd <= next_xgxs_txd;
191
                xgxs_txc <= next_xgxs_txc;
192
 
193
                curr_state_pad <= next_state_pad;
194
 
195
 
196
                txhfifo_wdata <= next_txhfifo_wdata;
197
                txhfifo_wstatus <= next_txhfifo_wstatus;
198
 
199
 
200
                //---
201
                // Reset byte count on SOP
202
 
203
 
204
 
205
                if (next_txhfifo_wstatus[`TXSTATUS_SOP]) begin
206
                        byte_cnt <= 14'd8;
207
                end
208
                else if (next_txhfifo_wstatus[`TXSTATUS_VALID]) begin
209
                        byte_cnt <= byte_cnt + 14'd8;
210
                end
211
 
212
 
213
                // ========================================
214
                // ============CRC_CALC====================
215
                // ========================================
216
 
217
 
218
                if (txhfifo_wstatus[`TXSTATUS_VALID]) begin
219
 
220
                        crc32_d64 <= next_crc32_data64_be(reverse_64b(txhfifo_wdata), crc_data, 3'b000);
221
 
222
                end
223
 
224
                if (txhfifo_wstatus[`TXSTATUS_VALID] && txhfifo_wstatus[`TXSTATUS_EOP]) begin
225
 
226
 
227
                        crc32_tx <= ~reverse_32b(next_crc32_data64_be(reverse_64b(txhfifo_wdata), crc32_d64, txhfifo_wstatus[2:0]));
228
 
229
 
230
                end
231
 
232
 
233
        end
234
 
235
end
236
 
237
 
238
        always @(crc32_tx or curr_state_enc or eop
239
                or txhfifo_wdata_d1
240
                or txhfifo_wstatus) begin
241
 
242
        next_state_enc = curr_state_enc;
243
 
244
 
245
        next_eop = eop;
246
 
247
        next_xgxs_txd = {8{`IDLE}};
248
        next_xgxs_txc = 8'hff;
249
 
250
 
251
 
252
 
253
        case (curr_state_enc)
254
 
255
                SM_PREAMBLE: begin
256
 
257
                        // On reading SOP 
258
 
259
                        if (txhfifo_wstatus[`TXSTATUS_SOP] && txhfifo_wstatus[`TXSTATUS_VALID]) begin
260
 
261
                                next_xgxs_txd = {`SFD, {6{`PREAMBLE}}, `START};
262
                                next_xgxs_txc = 8'h01;
263
 
264
                                next_state_enc = SM_TX;
265
 
266
                        end
267
                        else begin
268
                                next_state_enc = SM_PREAMBLE;
269
 
270
                        end
271
 
272
 
273
 
274
                end
275
 
276
                SM_TX: begin
277
 
278
                        next_xgxs_txd = txhfifo_wdata_d1;
279
                        next_xgxs_txc = 8'h00;
280
 
281
 
282
 
283
                        // Wait for EOP indication to be read from the fifo, then
284
                        // transition to next state.
285
 
286
                        if (txhfifo_wstatus[`TXSTATUS_EOP]) begin
287
 
288
                                next_state_enc = SM_EOP;
289
 
290
                        end
291
                        else if (txhfifo_wstatus[`TXSTATUS_SOP]) begin
292
 
293
                                // Failure condition, we did not see EOP and there
294
                                // is no more data in fifo or SOP, force end of packet transmit.
295
                                next_state_enc = SM_TERM_FAIL;
296
 
297
                        end
298
 
299
                        next_eop[0] = txhfifo_wstatus[2:0] == 3'd1;
300
                        next_eop[1] = txhfifo_wstatus[2:0] == 3'd2;
301
                        next_eop[2] = txhfifo_wstatus[2:0] == 3'd3;
302
                        next_eop[3] = txhfifo_wstatus[2:0] == 3'd4;
303
                        next_eop[4] = txhfifo_wstatus[2:0] == 3'd5;
304
                        next_eop[5] = txhfifo_wstatus[2:0] == 3'd6;
305
                        next_eop[6] = txhfifo_wstatus[2:0] == 3'd7;
306
                        next_eop[7] = txhfifo_wstatus[2:0] == 3'd0;
307
 
308
                end
309
 
310
                SM_EOP:
311
                        begin
312
 
313
                        // Insert TERMINATE character in correct lane depending on position
314
                        // of EOP read from fifo. Also insert CRC read from control fifo.
315
 
316
                        if (eop[0]) begin
317
                                next_xgxs_txd = {{2{`IDLE}}, `TERMINATE,
318
                                                crc32_tx[31:0], txhfifo_wdata_d1[7:0]};
319
                                next_xgxs_txc = 8'b11100000;
320
                        end
321
 
322
                        else if (eop[1]) begin
323
                                next_xgxs_txd = {`IDLE, `TERMINATE,
324
                                                crc32_tx[31:0], txhfifo_wdata_d1[15:0]};
325
                                next_xgxs_txc = 8'b11000000;
326
                        end
327
 
328
                        else if (eop[2]) begin
329
                                next_xgxs_txd = {`TERMINATE, crc32_tx[31:0], txhfifo_wdata_d1[23:0]};
330
                                next_xgxs_txc = 8'b10000000;
331
                        end
332
 
333
                        else if (eop[3]) begin
334
                                next_xgxs_txd = {crc32_tx[31:0], txhfifo_wdata_d1[31:0]};
335
                                next_xgxs_txc = 8'b00000000;
336
                        end
337
 
338
                        else if (eop[4]) begin
339
                                next_xgxs_txd = {crc32_tx[23:0], txhfifo_wdata_d1[39:0]};
340
                                next_xgxs_txc = 8'b00000000;
341
                        end
342
 
343
                        else if (eop[5]) begin
344
                                next_xgxs_txd = {crc32_tx[15:0], txhfifo_wdata_d1[47:0]};
345
                                next_xgxs_txc = 8'b00000000;
346
                        end
347
 
348
                        else if (eop[6]) begin
349
                                next_xgxs_txd = {crc32_tx[7:0], txhfifo_wdata_d1[55:0]};
350
                                next_xgxs_txc = 8'b00000000;
351
                        end
352
 
353
                        else if (eop[7]) begin
354
                                next_xgxs_txd = {txhfifo_wdata_d1[63:0]};
355
                                next_xgxs_txc = 8'b00000000;
356
                        end
357
 
358
 
359
 
360
                        if (|eop[2:0]) begin
361
 
362
                                if (!txhfifo_wstatus[`TXSTATUS_VALID]) begin
363
 
364
                                        next_state_enc = SM_PREAMBLE;
365
 
366
                                end
367
                        end
368
 
369
                        if (|eop[7:3]) begin
370
                                next_state_enc = SM_TERM;
371
                        end
372
 
373
                end
374
 
375
                SM_TERM: begin
376
 
377
                // Insert TERMINATE character in correct lane depending on position
378
                // of EOP read from fifo. Also insert CRC read from control fifo.
379
 
380
                        if (eop[3]) begin
381
                                next_xgxs_txd = {{7{`IDLE}}, `TERMINATE};
382
                                next_xgxs_txc = 8'b11111111;
383
                        end
384
 
385
                        else if (eop[4]) begin
386
                                next_xgxs_txd = {{6{`IDLE}}, `TERMINATE, crc32_tx[31:24]};
387
                                next_xgxs_txc = 8'b11111110;
388
                        end
389
 
390
                        else if (eop[5]) begin
391
                                next_xgxs_txd = {{5{`IDLE}}, `TERMINATE, crc32_tx[31:16]};
392
                                next_xgxs_txc = 8'b11111100;
393
                        end
394
 
395
                        else if (eop[6]) begin
396
                                next_xgxs_txd = {{4{`IDLE}}, `TERMINATE, crc32_tx[31:8]};
397
                                next_xgxs_txc = 8'b11111000;
398
                        end
399
 
400
                        else if (eop[7]) begin
401
                                next_xgxs_txd = {{3{`IDLE}}, `TERMINATE, crc32_tx[31:0]};
402
                                next_xgxs_txc = 8'b11110000;
403
                        end
404
 
405
                        next_state_enc = SM_PREAMBLE;
406
 
407
 
408
                end
409
 
410
                SM_TERM_FAIL: begin
411
 
412
                        next_xgxs_txd = {{7{`IDLE}}, `TERMINATE};
413
                        next_xgxs_txc = 8'b11111111;
414
                        next_state_enc = SM_PREAMBLE;
415
                end
416
 
417
 
418
                default: begin
419
 
420
                        next_state_enc = SM_PREAMBLE;
421
                end
422
 
423
        endcase
424
 
425
        end
426
 
427
 
428
always @(/*AS*//*crc32_d64 or txhfifo_wen or txhfifo_wstatus*/ *) begin
429
 
430
    if (txhfifo_wstatus[`TXSTATUS_SOP]) begin
431
        crc_data = 32'hffffffff;
432
    end
433
    else begin
434
        crc_data = crc32_d64;
435
    end
436
 
437
end
438
 
439
 
440
 
441
// ==================================== STATE_MACHINE FOR PADDING =========================
442
 
443
 
444
always @(/*AS*//*byte_cnt or curr_state_pad or txdfifo_rdata
445
         or txdfifo_rempty or txdfifo_ren_d1 or txdfifo_rstatus
446
         or txhfifo_walmost_full*/ *) begin
447
 
448
        next_state_pad = curr_state_pad;
449
 
450
        next_txhfifo_wdata = txdfifo_rdata;
451
        next_txhfifo_wstatus = txdfifo_rstatus;
452
 
453
 
454
        case (curr_state_pad)
455
 
456
        SM_PAD_EQ: begin
457
 
458
 
459
                if (txdfifo_rstatus[`TXSTATUS_VALID]) begin
460
 
461
 
462
              // On EOP, decide if padding is required for this packet.
463
 
464
                        if (txdfifo_rstatus[`TXSTATUS_EOP]) begin
465
 
466
                                if (byte_cnt < 14'd56) begin
467
                                        next_txhfifo_wstatus = `TXSTATUS_NONE;
468
                                        next_state_pad = SM_PAD_PAD;
469
                                end
470
                                else if (       byte_cnt == 14'd56 &&
471
                                        (txdfifo_rstatus[2:0] == 3'd1 ||
472
                                        txdfifo_rstatus[2:0] == 3'd2 ||
473
                                        txdfifo_rstatus[2:0] == 3'd3))
474
                                begin
475
 
476
                                        // Pad up to LANE3, keep the other 4 bytes for crc that will
477
                                        // be inserted by dequeue engine.
478
 
479
                                        next_txhfifo_wstatus[2:0] = 3'd4;
480
 
481
                                        // Pad end bytes with zeros.
482
 
483
                                        if (txdfifo_rstatus[2:0] == 3'd1)
484
                                                next_txhfifo_wdata[31:8] = 24'b0;
485
                                        if (txdfifo_rstatus[2:0] == 3'd2)
486
                                                next_txhfifo_wdata[31:16] = 16'b0;
487
                                        if (txdfifo_rstatus[2:0] == 3'd3)
488
                                                next_txhfifo_wdata[31:24] = 8'b0;
489
                                end
490
 
491
 
492
                        end
493
 
494
                end
495
 
496
        end
497
 
498
        SM_PAD_PAD: begin
499
 
500
          //---
501
          // Pad packet to 64 bytes by writting zeros to holding fifo.
502
 
503
 
504
 
505
                next_txhfifo_wdata = 64'b0;
506
                next_txhfifo_wstatus = `TXSTATUS_NONE;
507
 
508
                if (byte_cnt == 14'd56) begin
509
 
510
                        // Pad up to LANE3, keep the other 4 bytes for crc that will
511
                        // be inserted by dequeue engine.
512
 
513
                        next_txhfifo_wstatus[`TXSTATUS_EOP] = 1'b1;
514
                        next_txhfifo_wstatus[2:0] = 3'd4;
515
 
516
                        next_state_pad = SM_PAD_EQ;
517
 
518
                end
519
 
520
        end
521
 
522
        default: begin
523
 
524
                next_state_pad = SM_PAD_EQ;
525
        end
526
 
527
        endcase
528
 
529
end
530
 
531
 
532
endmodule
533
 

powered by: WebSVN 2.1.0

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