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

Subversion Repositories turbo8051

[/] [turbo8051/] [trunk/] [rtl/] [gmac/] [mac/] [g_tx_fsm.v] - Blame information for rev 12

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 12 dinesha
//////////////////////////////////////////////////////////////////////
2
////                                                              ////
3
////  Tubo 8051 cores MAC Interface Module                        ////
4
////                                                              ////
5
////  This file is part of the Turbo 8051 cores project           ////
6
////  http://www.opencores.org/cores/turbo8051/                   ////
7
////                                                              ////
8
////  Description                                                 ////
9
////  Turbo 8051 definitions.                                     ////
10
////                                                              ////
11
////  To Do:                                                      ////
12
////    nothing                                                   ////
13
////                                                              ////
14
////  Author(s):                                                  ////
15
////      - Dinesh Annayya, dinesha@opencores.org                 ////
16
////                                                              ////
17
//////////////////////////////////////////////////////////////////////
18
////                                                              ////
19
//// Copyright (C) 2000 Authors and OPENCORES.ORG                 ////
20
////                                                              ////
21
//// This source file may be used and distributed without         ////
22
//// restriction provided that this copyright statement is not    ////
23
//// removed from the file and that any derivative work contains  ////
24
//// the original copyright notice and the associated disclaimer. ////
25
////                                                              ////
26
//// This source file is free software; you can redistribute it   ////
27
//// and/or modify it under the terms of the GNU Lesser General   ////
28
//// Public License as published by the Free Software Foundation; ////
29
//// either version 2.1 of the License, or (at your option) any   ////
30
//// later version.                                               ////
31
////                                                              ////
32
//// This source is distributed in the hope that it will be       ////
33
//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
34
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
35
//// PURPOSE.  See the GNU Lesser General Public License for more ////
36
//// details.                                                     ////
37
////                                                              ////
38
//// You should have received a copy of the GNU Lesser General    ////
39
//// Public License along with this source; if not, download it   ////
40
//// from http://www.opencores.org/lgpl.shtml                     ////
41
////                                                              ////
42
//////////////////////////////////////////////////////////////////////
43
//`timescale 1ns/100ps
44
 
45
/***************************************************************
46
 Description:
47
 
48
 tx_fsm.v: Frames are queued in TX FIFO, when the TX FIFO has enough
49
 data to sustain a 100Mb or 10 Mb transfer on the TX transmit is enabled.
50
 Each dword has 3 extra bits, which indicate the end of the frame and
51
 the number of valid bytes in the current dword.
52
 
53
 ***********************************************************************/
54
 
55
 
56
module g_tx_fsm (
57
                 //Outputs
58
                 //FIFO
59
                 tx_commit_read,
60
                 tx_dt_rd,
61
 
62
                 //FCS
63
                 tx2tc_fcs_active,
64
                 tx2tc_gen_crc,
65
 
66
                 //MII interface
67
                 tx2mi_strt_preamble,
68
                 tx2mi_byte_valid,
69
                 tx2mi_byte,
70
                 tx2mi_end_transmit,
71
                 phy_tx_en,
72
                 tx_ch_en,
73
 
74
                 //Application
75
                 tx_sts_vld,
76
                 tx_sts_byte_cntr,
77
                 tx_sts_fifo_underrun,
78
 
79
                 //Inputs
80
                 //FIFO
81
                 app_tx_rdy,
82
                 tx_end_frame,
83
                 app_tx_dt_in,
84
                 app_tx_fifo_empty,
85
 
86
                 //dfl and back
87
                 df2tx_dfl_dn,
88
 
89
                 //application
90
                 app_send_pause,
91
 
92
                 //FCS
93
                 tc2tx_fcs,
94
 
95
                 //Configuration
96
                 cf2tx_tstate_mode,
97
                 cf2tx_ch_en,
98
                 cf2tx_pad_enable,
99
                 cf2tx_append_fcs,
100
                 cf_mac_mode,
101
                 cf_mac_sa,
102
                 cf2tx_pause_quanta,
103
                 cf2tx_force_bad_fcs,
104
 
105
                 //RX pause
106
                 rx2tx_pause,
107
                 send_pause_active_out,
108
                 app_clk,
109
                 set_fifo_undrn,
110
 
111
                 //MII interface
112
                 mi2tx_byte_ack,
113
                 tx_clk,
114
                 tx_reset_n,
115
                 app_reset_n);
116
 
117
 
118
parameter CORE_MIN_FRAME_SIZE = 16'h40;  //64 bytes => 
119
// (12(add)+2(len)+46(pay) + 4CRC)*2
120
parameter CORE_MIN_FRAME_COL_SIZE = 16'h40;  //63 bytes => 
121
// tx_fsm lags MII by one byte
122
parameter CORE_PAYLOAD_SIZE = 16'h3C ; //60 bytes => 
123
// (12(add)+2(len)+46(pay))*2
124
 
125
 
126
  input        cf2tx_ch_en;           //transmit enable application clock
127
  input        cf2tx_tstate_mode;     //used for OFN's tstate enable on authentication interface
128
  input        app_tx_rdy;            //tx fifo management, enough buffer to tx
129
  input        tx_end_frame;          //Current DWORD marks end of frame 
130
  input [7:0]  app_tx_dt_in;          //double word data from the TX fifo mgmt
131
  input        app_tx_fifo_empty;     //TX fifo is empty, if there were a data
132
                                      //data request when app_tx_fifo_empty is asserted
133
                                      //would result in FIFO underrun and error cond
134
  input        app_send_pause;
135
  input [31:0] tc2tx_fcs;
136
 
137
  //defferral inputs
138
  input        df2tx_dfl_dn;          //IPG time between frames is satisfied
139
 
140
  //configuration inputs
141
  input        cf2tx_pad_enable;      //pad the TX frame if they are small
142
  input        cf2tx_append_fcs;      //on every TX, compute and append FCS, when
143
                                      //cf2tx_pad_enable and the current frame is small
144
                                      //FCS is computed and appended to the frame
145
                                      //irrespective of this signal
146
  input        cf_mac_mode;           // 1 is GMII 0 10/100
147
  input [47:0] cf_mac_sa;
148
  input [15:0] cf2tx_pause_quanta;
149
  input        cf2tx_force_bad_fcs;
150
  //RX pause frame received
151
  input        rx2tx_pause;           //in full duplex mode, the RX has received
152
                                      //a pause frame, hence the TX is requested to
153
                                      //hold transfers after the transmission of the
154
                                      //current transfer. level signal
155
                                      //from MII or RMII
156
  input        mi2tx_byte_ack;        //MII interface accepted last byte
157
  input        tx_clk;
158
  input        tx_reset_n;
159
  input        app_reset_n;
160
 
161
  //tx fifo management outputs
162
  output       tx_commit_read;        //64 bytes have been transmitted successfully
163
  //hence advance the rd pointer
164
  output       tx_dt_rd;              //get net dword from the TX FIFO
165
  //FCS interface
166
  output       tx2tc_fcs_active;      //FCS being shipped to RMII or MII interface
167
  output       tx2tc_gen_crc;         //update the CRC with new byte
168
 
169
 
170
  //MII or RMII interface signals
171
  output       tx2mi_strt_preamble;   //ask RMII or MII interface to send preamable
172
  output       tx2mi_byte_valid;      //current byte to RMII or MII is valid
173
  output [7:0] tx2mi_byte;            //data to RMII and MII interface
174
  output       tx2mi_end_transmit;    //frame transfer done
175
  output       tx_sts_vld;            //tx status is valid
176
  output [15:0] tx_sts_byte_cntr;
177
  output        tx_sts_fifo_underrun;
178
  output        tx_ch_en;   // MANDAR
179
 
180
  input         phy_tx_en;   // mfilardo ofn auth fix.
181
 
182
  input         app_clk;
183
  output        send_pause_active_out;
184
  output    set_fifo_undrn; // Description: At GMII Interface ,
185
                            // abug after a transmit fifo underun was found.
186
                            // The packet after a packet that 
187
                            // underran has 1 too few bytes .
188
 
189
 
190
  parameter     mn_idle_st = 3'd0;
191
  parameter     mn_snd_full_dup_frm_st = 3'd1;
192
 
193
  parameter     fcs_idle_st = 0;
194
  parameter     fcs_snd_st = 1;
195
 
196
  parameter     dt_idle_st =      12'b000000000000;
197
  parameter     dt_xfr_st =       12'b000000000001;
198
  parameter     dt_pad_st =       12'b000000000010;
199
  parameter     dt_fcs_st =       12'b000000000100;
200
  parameter     dt_pause_xfr_st = 12'b000010000000;
201
  parameter     dt_pause_pad_st = 12'b000100000000;
202
  parameter     dt_pause_fcs_st = 12'b001000000000;
203
 
204
 
205
  wire          tx_commit_read;
206
  wire          tx_dt_rd;            //request TX FIFO for more data
207
  wire          tx2tc_fcs_active;    //FCS is currently transmitted
208
  wire          tx2tc_gen_crc;
209
  wire          tx2mi_strt_preamble;
210
  wire          tx2mi_end_transmit;
211
  wire [7:0]     tx2mi_byte;
212
  wire          tx2mi_byte_valid;
213
  wire          cfg_force_bad_fcs_pulse;
214
  reg [15:0]     tx_sts_byte_cntr;
215
  reg           tx_sts_fifo_underrun;
216
 
217
 
218
  reg [11:0]     curr_dt_st, nxt_dt_st;
219
  reg           tx_fcs_dn, tx_fcs_dn_reg; //FCS fsm on completion of appending FCS
220
  reg           curr_fcs_st, nxt_fcs_st;  //FSM for  FCS
221
  reg           fcs_active;               //FCS is currently transmitted
222
 
223
  reg           init_fcs_select;          //initiliaze FCS mux select
224
  reg           clr_bad_fcs;              //tx_reset the bad FCS requirement
225
  reg           clr_pad_byte;             //clear the padded condition
226
  reg [2:0]      fcs_mux_select;           //mux select for  FCS
227
  reg           send_bad_fcs;             //registered send bad FCS requirement
228
  reg           set_bad_fcs;              //set the above register
229
  reg [15:0]     tx_byte_cntr;             //count the number of bytes xfr'ed
230
  reg           tx_fsm_rd;                //request TX FIFO for more data
231
  reg           tx_byte_valid;            //current byte to MII is valdi
232
  reg           strt_fcs, strt_fcs_reg;   //data is done, send FCS
233
  reg           frm_padded;               //current frame is padded
234
 
235
 
236
  reg           set_pad_byte;             //send zero filled bytes
237
  reg           e_tx_sts_vld;             //current packet is transferred
238
  reg           tx_sts_vld;               //02999
239
  reg           strt_preamble;
240
  reg [7:0]      tx_byte;
241
  reg [7:0]      tx_fsm_dt_reg;
242
  reg           tx_end_frame_reg;
243
  reg           tx_lst_xfr_dt, tx_lst_xfr_fcs;
244
  reg           commit_read;
245
  reg           set_max_retry_reached;
246
  reg           gen_tx_crc;
247
  reg           set_fifo_undrn, clr_fifo_undrn, fifo_undrn;
248
  reg           commit_read_sent;
249
  reg           clr_first_dfl, set_first_dfl;
250
 
251
  wire          tx_lst_xfr;
252
  wire          tx_pause_sync;
253
  reg           inc_pause_index, clr_pause_index;
254
  reg           send_pause_active;
255
  wire          send_pause_sync;
256
 
257
  reg [4:0]      pause_index;
258
 
259
  reg           tx_lst_xfr_fcs_reg;
260
  wire [15:0]    tx_byte_cntr_int;
261
 
262
  reg           cur_idle_st_del;
263
 
264
  reg           app_tx_rdy_dly;
265
 
266
  reg           send_pause_active_s1;
267
  reg           send_pause_active_out;
268
 
269
  always @(posedge app_clk or negedge app_reset_n) begin
270
    if (!app_reset_n) begin
271
      send_pause_active_s1 <= 1'b0;
272
      send_pause_active_out <= 1'b0;
273
    end
274
    else begin
275
      send_pause_active_s1 <= send_pause_active;
276
      send_pause_active_out <= send_pause_active_s1;
277
    end
278
  end
279
 
280
  always @(posedge tx_clk or negedge tx_reset_n) begin
281
    if (!tx_reset_n) begin
282
      app_tx_rdy_dly <= 1'b0;
283
    end
284
    else begin
285
      app_tx_rdy_dly <= app_tx_rdy;
286
    end
287
  end
288
 
289
 
290
 
291
  assign        tx_commit_read = commit_read;
292
  assign        tx_dt_rd = tx_fsm_rd;
293
  assign        tx2tc_fcs_active = fcs_active;
294
  assign        tx2tc_gen_crc = gen_tx_crc;
295
  assign        tx2mi_strt_preamble = strt_preamble;
296
  assign        tx2mi_byte_valid = tx_byte_valid;
297
  assign        tx2mi_byte = tx_byte;
298
  assign        tx2mi_end_transmit = tx_lst_xfr;
299
 
300
  assign        tx_lst_xfr = tx_lst_xfr_dt || tx_lst_xfr_fcs;
301
 
302
//To take care of 1 less byte count when fcs is not appended.
303
   assign tx_byte_cntr_int = ((curr_dt_st == dt_fcs_st)  ||
304
                              (curr_dt_st == dt_pause_fcs_st)) ? tx_byte_cntr : tx_byte_cntr + 16'h1;
305
 
306
  always @(posedge tx_clk or negedge tx_reset_n)
307
    begin
308
      if (!tx_reset_n)
309
        begin
310
          tx_sts_vld <= 1'b0;
311
          tx_sts_byte_cntr <= 16'b0;
312
          tx_sts_fifo_underrun <= 1'b0;
313
        end // if (!tx_reset_n)
314
      else
315
        begin
316
          tx_sts_vld <= e_tx_sts_vld;
317
          if (e_tx_sts_vld)
318
            begin
319
              tx_sts_byte_cntr <= tx_byte_cntr_int;
320
              tx_sts_fifo_underrun <= fifo_undrn || set_fifo_undrn;
321
            end
322
        end // else: !if(!tx_reset_n)
323
    end // always @ (posedge tx_clk or negedge tx_reset_n)
324
 
325
 
326
 
327
 
328
  half_dup_dble_reg U_dble_reg1 (
329
                        //outputs
330
                        .sync_out_pulse(tx_pause_sync),
331
                        //inputs
332
                        .in_pulse(rx2tx_pause),
333
                        .dest_clk(tx_clk),
334
                        .reset_n(tx_reset_n)
335
                        );
336
 
337
  half_dup_dble_reg U_dble_reg2 (
338
                        //outputs
339
                        .sync_out_pulse(tx_ch_en),
340
                        //inputs
341
                        .in_pulse(cf2tx_ch_en),
342
                        .dest_clk(tx_clk),
343
                        .reset_n(tx_reset_n)
344
                        );
345
 
346
 
347
  half_dup_dble_reg U_dble_reg3 (
348
                        //outputs
349
                        .sync_out_pulse(send_pause_sync),
350
                        //inputs
351
                        .in_pulse(app_send_pause),
352
                        .dest_clk(tx_clk),
353
                        .reset_n(tx_reset_n)
354
                        );
355
 
356
  half_dup_dble_reg U_dble_reg4 (
357
                        //outputs
358
                        .sync_out_pulse(cfg_force_bad_fcs_pulse),
359
                        //inputs
360
                        .in_pulse(cf2tx_force_bad_fcs),
361
                        .dest_clk(tx_clk),
362
                        .reset_n(tx_reset_n)
363
                        );
364
 
365
  always @(posedge tx_clk or negedge tx_reset_n)
366
    begin
367
      if (!tx_reset_n)
368
        cur_idle_st_del <= 1'b1;
369
      else
370
        cur_idle_st_del <= (curr_dt_st==dt_idle_st);
371
    end
372
 
373
  //Data pump, this state machine gets triggered by TX FIFO
374
  //This FSM control's the MUX loging to channel the 32 bit
375
  //data to byte wide and also keeps track of the end of the
376
  //frame and the valid bytes for the last double word. tx_sts_vld
377
  //is generated by this fsm.
378
  //Collission handling, retry operations are done in this FSM.
379
  always @(posedge tx_clk or negedge tx_reset_n)
380
    begin
381
      if (!tx_reset_n)
382
        curr_dt_st <= dt_idle_st;
383
      else if (tx_ch_en)
384
        curr_dt_st <= nxt_dt_st;
385
      else
386
        curr_dt_st <= dt_idle_st;
387
    end // always @ (posedge tx_clk or negedge tx_reset_n)
388
 
389
  //combinatorial process
390
  //always @(curr_dt_st or mi2tx_byte_ack or app_tx_fifo_empty 
391
  always @(curr_dt_st or mi2tx_byte_ack or app_tx_fifo_empty
392
           or tx_end_frame_reg or commit_read_sent
393
           or tx_byte_cntr or tx_fcs_dn_reg or cf2tx_pad_enable or tx_ch_en
394
           or df2tx_dfl_dn or tx_pause_sync or app_tx_rdy
395
           or strt_fcs_reg
396
           or tx_end_frame or tx_clk
397
           or cf2tx_append_fcs
398
           or app_tx_rdy_dly or send_pause_sync or pause_index or cur_idle_st_del)
399
    begin
400
      nxt_dt_st = curr_dt_st;
401
      tx_fsm_rd = 0;
402
      tx_byte_valid = 0;
403
      set_bad_fcs = 0;
404
      strt_fcs = 0;
405
      set_pad_byte = 0;
406
      set_max_retry_reached = 0;
407
      e_tx_sts_vld = 0;
408
      commit_read = 0;
409
      strt_preamble = 0;
410
      tx_lst_xfr_dt = 0;
411
      clr_pad_byte = 0;
412
      set_fifo_undrn = 0;
413
      clr_fifo_undrn = 0;
414
      clr_first_dfl = 0;
415
      set_first_dfl = 0;
416
      send_pause_active = 0;
417
      inc_pause_index = 0;
418
      clr_pause_index = 0;
419
      case (curr_dt_st)
420
        dt_idle_st :
421
          begin
422
            //clear early state
423
            clr_pad_byte = 1;
424
            clr_fifo_undrn = 1;
425
            clr_first_dfl = 1'b1;
426
            //wait until there is enough data in the TX FIFO
427
            //and tx_enabled and not waiting for pause period
428
            //in the case of full duplex
429
            if (tx_ch_en) //config, channel enable
430
              begin
431
                 if (send_pause_sync  && df2tx_dfl_dn)
432
                 begin
433
                     // this ifdef is a bug fix.  A pending pause can cause ifg to be 1 cycle short.  
434
                        nxt_dt_st = dt_pause_xfr_st;
435
                        strt_preamble = 1;
436
                      end
437
                 else if (app_tx_rdy && df2tx_dfl_dn && !tx_pause_sync)
438
                 begin
439
                        tx_fsm_rd = 1;
440
                        nxt_dt_st = dt_xfr_st;
441
                        strt_preamble = 1;
442
                 end
443
                 else
444
                    nxt_dt_st = dt_idle_st;
445
              end // if (tx_ch_en)
446
            else
447
              nxt_dt_st = dt_idle_st;
448
          end // case: dt_idle_st
449
 
450
        dt_xfr_st :
451
          begin
452
            tx_byte_valid = 1;
453
            //compare the mux_select to max bytes to be transmitted
454
            //on the last dword of the frame
455
            if (mi2tx_byte_ack && (tx_end_frame_reg))
456
              begin
457
                // If it is end of frame detection and the count
458
                // indicates that there is no need for padding then if
459
                // pad is enabled dont check for cf2tx_append_fcs and Append
460
                // the CRC with the data packet
461
                if ((tx_byte_cntr >= ( CORE_PAYLOAD_SIZE - 1)) && cf2tx_append_fcs)
462
                  begin
463
                    strt_fcs = 1;
464
                    nxt_dt_st = dt_fcs_st;
465
                  end // if (cf2tx_append_fcs)
466
                else
467
                  //ending the current transfer, check the frame size
468
                  //padding or FCS needs to be performed
469
                  if (tx_byte_cntr < ( CORE_PAYLOAD_SIZE - 1))
470
                    begin
471
                      //less than min frame size, check to see if
472
                      //padding can be done
473
                      if(cf2tx_pad_enable)
474
                        begin
475
                          nxt_dt_st = dt_pad_st;
476
                        end // if (cf2tx_pad_enable)
477
                      else
478
                        begin
479
                          //if no padding, check to see if FCS needs
480
                          //to be computed
481
                          if (cf2tx_append_fcs)
482
                            begin
483
                              strt_fcs = 1;
484
                              nxt_dt_st = dt_fcs_st;
485
                            end // if (cf2tx_append_fcs)
486
                          else
487
                            //if no FCS, complete the transfer
488
                            begin
489
                              e_tx_sts_vld = 1;
490
                              commit_read = 1;
491
                              nxt_dt_st = dt_idle_st;
492
                            end // else: !if(cf2tx_append_fcs)
493
                        end // else: !if(cf2tx_pad_enable)
494
                    end // if (tx_byte_cntr < ( CORE_MIN_FRAME_SIZE - 1))
495
                  else
496
                    //minimmum frame sent, check to see if FCS needs to
497
                    //be computed else transfer is done
498
                    begin
499
                      if (cf2tx_append_fcs)
500
                        begin
501
                          strt_fcs = 1;
502
                          nxt_dt_st = dt_fcs_st;
503
                        end // if (cf2tx_append_fcs)
504
                      else
505
                        begin
506
                          commit_read = !commit_read_sent;
507
                          e_tx_sts_vld = 1;
508
                          nxt_dt_st = dt_idle_st;
509
                        end // else: !if(cf2tx_append_fcs)
510
                    end // else: !if(tx_byte_cntr < ( CORE_MIN_FRAME_SIZE - 1))
511
              end
512
            else if (mi2tx_byte_ack)
513
              begin
514
                //time to fetch the new dword
515
                //check to see if the fifo is empty
516
                //if it is then send the crc with last bit
517
                //inverted as bad CRC so that the destination
518
                //can throw away the frame
519
                if (app_tx_fifo_empty)
520
                  begin
521
                    //TX has encountered error, finish the current byte
522
                    //append wrong fcs
523
                    set_bad_fcs = 1;
524
                    strt_fcs = 1;
525
                    nxt_dt_st = dt_fcs_st;
526
                    set_fifo_undrn = 1;
527
                  end // if (mi2tx_byte_ack && ((mux_select == 1) ||...
528
                tx_fsm_rd = 1; //just to set error, or
529
                //get next word
530
              end // if (mi2tx_byte_ack && mux_selectl == 1)
531
            //provide end of transfer to MII/RMII interface
532
            //commit_read pointer
533
            if (mi2tx_byte_ack )
534
              commit_read = !commit_read_sent;
535
 
536
            if (tx_end_frame_reg)
537
              begin
538
                if (tx_byte_cntr < (CORE_PAYLOAD_SIZE - 1))
539
                  begin
540
                    if(!cf2tx_pad_enable)
541
                      begin
542
                        if (!cf2tx_append_fcs)
543
                          tx_lst_xfr_dt = 1;
544
                      end // if (!cf2tx_pad_enable)
545
                  end // if (tx_byte_cntr < (CORE_MIN_FRAME_SIZE - 1))
546
                else
547
                  begin
548
                    if (!cf2tx_append_fcs)
549
                      tx_lst_xfr_dt = 1;
550
                  end
551
              end // if ((mux_select == mux_max_select) && (tx_end_frame_reg))
552
          end // case: dt_xfr_st
553
 
554
        dt_pad_st :
555
          begin
556
            //wait until the padded data is enough to satisfy
557
            //the minimum packet size and then return to idle
558
            tx_byte_valid = 1;
559
            set_pad_byte = 1;
560
            //check to see if the 48 bytes are sent and then move to the
561
            //crc state
562
            if (mi2tx_byte_ack && (tx_byte_cntr == CORE_PAYLOAD_SIZE - 1))
563
                begin
564
                  strt_fcs = 1;
565
                  nxt_dt_st = dt_fcs_st;
566
             end // if (mi2tx_byte_ack && (tx_byte_cntr == CORE_PAYLOAD_SIZE - 1))
567
          end // case: dt_pad_st
568
 
569
        dt_fcs_st :
570
          begin
571
            if (tx_fcs_dn_reg && !strt_fcs_reg)
572
              //last byte of crc is transmitted to MII and
573
              //a new set of CRC is not transmitted to MII (this
574
              //could be because of JAM sequence)
575
              begin
576
                 //In the case of MII, while in this state the
577
                 //MII interface will be transferring the last
578
                 //byte to the PHY. If a collision is seen in this
579
                 //state then do the appropriate
580
                 commit_read = !commit_read_sent;
581
                 nxt_dt_st = dt_idle_st;
582
                 e_tx_sts_vld = 1;
583
              end // if (tx_fcs_dn)
584
              else
585
              begin
586
                nxt_dt_st = dt_fcs_st;
587
              end // else: !if(tx_fcs_dn)
588
          end // case: dt_fcs_st
589
 
590
        dt_pause_xfr_st :
591
          begin
592
            tx_byte_valid = 1;
593
            send_pause_active = 1;
594
            // Send the Pause Frame out 
595
            if (mi2tx_byte_ack)
596
              begin
597
                if (pause_index == 5'd18)
598
                  begin
599
                    clr_pause_index = 1;
600
                    nxt_dt_st = dt_pause_pad_st;
601
                  end
602
                else
603
                  begin
604
                    inc_pause_index = 1;
605
                    nxt_dt_st = dt_pause_xfr_st;
606
                  end
607
              end
608
            else
609
              begin
610
                nxt_dt_st = dt_pause_xfr_st;
611
              end
612
          end // case: dt_pause_xfr_st
613
 
614
        dt_pause_pad_st :
615
          begin
616
            // Append Padding to the Packet
617
            tx_byte_valid = 1;
618
            set_pad_byte = 1;
619
            if (mi2tx_byte_ack && (tx_byte_cntr == CORE_PAYLOAD_SIZE - 1))
620
              begin
621
                strt_fcs = 1;
622
                nxt_dt_st = dt_pause_fcs_st;
623
              end // if (mi2tx_byte_ack && 
624
            // (tx_byte_cntr == CORE_PAYLOAD_SIZE - 1))
625
            else
626
              nxt_dt_st = dt_pause_pad_st;
627
          end // case: dt_pause_pad_st
628
 
629
        dt_pause_fcs_st :
630
          begin
631
            // Wait for the FCS to be sent
632
            if (tx_fcs_dn_reg)
633
              begin
634
                e_tx_sts_vld = 1;
635
                nxt_dt_st = dt_idle_st;
636
              end
637
            else
638
              begin
639
                nxt_dt_st = dt_pause_fcs_st;
640
              end
641
          end // case: dt_pause_fcs_st
642
 
643
 
644
        default :
645
          begin
646
            nxt_dt_st = dt_idle_st;
647
          end
648
      endcase // case (curr_dt_st)
649
    end // always @ (curr_dt_st or )
650
 
651
  //counter to track the number of bytes transferred excluding
652
  //the preamble and SOF
653
  always @(posedge tx_clk or negedge tx_reset_n)
654
    begin
655
      if (!tx_reset_n)
656
        begin
657
          tx_byte_cntr <= 16'd0;
658
        end // if (!tx_reset_n)
659
      else
660
        begin
661
          if (mi2tx_byte_ack)
662
            begin
663
              tx_byte_cntr <= tx_byte_cntr + 1;
664
            end // if (mi2tx_byte_ack)
665
          else if (strt_preamble)
666
            begin
667
              tx_byte_cntr <= 16'd0;
668
            end // else: !if(mi2tx_byte_ack)
669
        end // else: !if(!tx_reset_n)
670
    end // always @ (posedge tx_clk or negedge tx_reset_n)
671
 
672
// So, introduce strt_preamble_pls to compensate for delay.
673
  reg s_p_d1, s_p_d2, s_p_d3;
674
  wire strt_preamble_pls;
675
  always @(posedge tx_clk or negedge tx_reset_n) begin
676
    if (!tx_reset_n) begin
677
           s_p_d1 <= 1'b0;
678
           s_p_d2 <= 1'b0;
679
           s_p_d3 <= 1'b0;
680
    end // if (!tx_reset_n)
681
    else begin
682
           s_p_d1 <= strt_preamble;
683
           s_p_d2 <= s_p_d1;
684
           s_p_d3 <= s_p_d2;
685
    end
686
  end // always
687
 
688
  wire strt_preamble_prog;
689
  assign strt_preamble_pls = strt_preamble || s_p_d1 || s_p_d2 || s_p_d3;
690
  assign strt_preamble_prog = strt_preamble;
691
//ECO fix, part1 end
692
 
693
  //fsm to transmit the FCS
694
  //synchronous process
695
  always @(posedge tx_clk or negedge tx_reset_n)
696
    begin
697
      if (!tx_reset_n)
698
        curr_fcs_st <= fcs_idle_st;
699
      else
700
        curr_fcs_st <= nxt_fcs_st;
701
    end // always @ (posedge tx_clk or negedge tx_reset_n)
702
 
703
  //set bad fcs requirement
704
  always @(posedge tx_clk or negedge tx_reset_n)
705
    begin
706
      if (!tx_reset_n)
707
        send_bad_fcs <= 0;
708
      else
709
        begin
710
          //if (set_bad_fcs)
711
          if (set_bad_fcs | cfg_force_bad_fcs_pulse)
712
            send_bad_fcs <= 1;
713
          else if (clr_bad_fcs)
714
            send_bad_fcs <= 0;
715
        end // else: !if(!tx_reset_n)
716
    end // always @ (posedge tx_clk or negedge tx_reset_n)
717
  //set the error condition flags
718
  always @(posedge tx_clk or negedge tx_reset_n)
719
    begin
720
      if (!tx_reset_n)
721
        begin
722
          fifo_undrn <= 0;
723
        end // if (!tx_reset_n)
724
      else
725
        begin
726
 
727
          if (set_fifo_undrn)
728
            fifo_undrn <= 1;
729
          else if (clr_fifo_undrn)
730
            fifo_undrn <= 0;
731
        end // else: !if(!tx_reset_n)
732
    end // always @ (posedge tx_clk or negedge tx_reset_n)
733
 
734
  //sync block for tx_fcs_dn
735
 
736
  always @(posedge tx_clk or negedge tx_reset_n)
737
    begin
738
      if (!tx_reset_n)
739
        begin
740
          strt_fcs_reg <= 0;
741
          tx_fcs_dn_reg <= 0;
742
          tx_lst_xfr_fcs_reg <= 0; //naveen 052799  
743
        end // if (!tx_reset_n)
744
      else
745
        begin
746
          tx_fcs_dn_reg <= tx_fcs_dn;
747
          strt_fcs_reg <= strt_fcs;
748
          tx_lst_xfr_fcs_reg <= tx_lst_xfr_fcs; //naveen 052799   
749
        end // else: !if(!tx_reset_n)
750
    end // always @ (posedge tx_clk or negedge tx_reset_n)
751
 
752
  //combinatorial process
753
  //bad fcs or good fcs could have been requested, in either case
754
  //the 8 bytes have to be shifted out, in the case of bad fcs
755
  //the last bit of the last byte will up toggled.
756
  always @(curr_fcs_st or mi2tx_byte_ack or fcs_mux_select or
757
           strt_fcs or strt_fcs_reg)
758
    begin
759
      nxt_fcs_st = curr_fcs_st;
760
      fcs_active = 0;
761
      init_fcs_select = 0;
762
      tx_fcs_dn = 0;
763
      clr_bad_fcs = 0;
764
      tx_lst_xfr_fcs = 0;
765
      case (curr_fcs_st)
766
        fcs_idle_st :
767
          if (strt_fcs || strt_fcs_reg)
768
            begin
769
              nxt_fcs_st = fcs_snd_st;
770
              init_fcs_select = 1;
771
            end // if (strt_fcs)
772
        fcs_snd_st :
773
          begin
774
            fcs_active = 1;
775
            if (fcs_mux_select == 3'd3)
776
              tx_lst_xfr_fcs = 1;
777
            if (mi2tx_byte_ack && fcs_mux_select == 3'd3)
778
              begin
779
                tx_fcs_dn = 1;
780
                clr_bad_fcs = 1;
781
                nxt_fcs_st = fcs_idle_st;
782
              end // if (mi2tx_byte_ack)
783
          end // case: fcs_snd_st
784
        default :
785
          begin
786
            nxt_fcs_st = fcs_idle_st;
787
          end
788
      endcase // case (curr_fcs_st)
789
    end // always @ (curr_fcs_st or)
790
 
791
  //fcs mux select counter
792
  always @(posedge tx_clk or negedge tx_reset_n)
793
    begin
794
      if (!tx_reset_n)
795
        fcs_mux_select <= 3'd0;
796
      else
797
        begin
798
          if (strt_fcs)
799
            fcs_mux_select <= 3'd0;
800
          else if (mi2tx_byte_ack)
801
            fcs_mux_select <= fcs_mux_select  + 1 ;
802
        end // else: !if(!tx_reset_n)
803
    end // always @ (posedge tx_clk or negedge tx_reset_n)
804
 
805
  //remmember if frame is padded
806
  always @(posedge tx_clk or negedge tx_reset_n)
807
    begin
808
      if (!tx_reset_n)
809
        frm_padded <= 0;
810
      else
811
        begin
812
          if (clr_pad_byte)
813
            frm_padded <= 0;
814
          else if (set_pad_byte)
815
            frm_padded <= 1;
816
        end // else: !if(!tx_reset_n)
817
    end // always @ (posedge tx_clk or negedge tx_reset_n)
818
 
819
 
820
  //register the TX fifo data on tx_fsm_rd and demux
821
  //it for byte access
822
  always @(posedge tx_clk or negedge tx_reset_n)
823
    begin
824
      if (!tx_reset_n)
825
        begin
826
          tx_fsm_dt_reg <= 8'd0;
827
          tx_end_frame_reg <= 0;
828
        end // if (!tx_reset_n)
829
      else
830
        begin
831
          if (tx_fsm_rd)
832
            begin
833
              tx_fsm_dt_reg <= app_tx_dt_in;
834
              tx_end_frame_reg <= tx_end_frame;
835
            end // if (tx_fsm_rd)
836
          if (e_tx_sts_vld)
837
            tx_end_frame_reg <= 0;
838
        end // else: !if(!tx_reset_n)
839
    end // always @ (posedge tx_clk or negedge tx_reset_n)
840
 
841
  //Pause index counters 
842
  always @(posedge tx_clk or negedge tx_reset_n)
843
    begin
844
      if (!tx_reset_n)
845
        pause_index <= 5'd0;
846
      else
847
        begin
848
          if (clr_pause_index)
849
            pause_index <= 5'd0;
850
          else if (inc_pause_index)
851
            pause_index <= pause_index + 1;
852
        end // else: !if(!tx_reset_n)
853
    end // always @ (posedge tx_clk or negedge tx_reset_n)
854
 
855
  //Data mux, is controlled either by the mux select from the
856
  //primary data flow or from the FCS mux select. When PAD
857
  //data option is used bytes of all zeros are transmitted
858
  always @(fcs_active or app_tx_dt_in or tc2tx_fcs
859
           or send_bad_fcs or fcs_mux_select or
860
           set_pad_byte or tx_fsm_dt_reg or send_pause_active or pause_index
861
           or cf_mac_sa or cf2tx_pause_quanta)
862
    begin
863
      if (send_pause_active)
864
        begin
865
          case (pause_index)
866
            5'd0 :
867
              tx_byte = 8'h01;
868
            5'd1 :
869
              tx_byte = 8'h80;
870
            5'd2 :
871
              tx_byte = 8'hc2;
872
            5'd3 :
873
              tx_byte = 8'h00;
874
            5'd4 :
875
              tx_byte = 8'h00;
876
            5'd5 :
877
              tx_byte = 8'h01;
878
            5'd6 :
879
              tx_byte = cf_mac_sa[7:0];
880
            5'd7 :
881
              tx_byte = cf_mac_sa[15:8];
882
            5'd8 :
883
              tx_byte = cf_mac_sa[23:16];
884
            5'd9 :
885
              tx_byte = cf_mac_sa[31:24];
886
            5'd10 :
887
              tx_byte = cf_mac_sa[39:32];
888
            5'd11 :
889
              tx_byte = cf_mac_sa[47:40];
890
            5'd12 :
891
              tx_byte = 8'h88;
892
            5'd13 :
893
              tx_byte = 8'h08;
894
            5'd14 :
895
              tx_byte = 8'h00;
896
            5'd15 :
897
              tx_byte = 8'h01;
898
            5'd16 :
899
              tx_byte = cf2tx_pause_quanta[15:8];
900
            5'd17 :
901
              tx_byte = cf2tx_pause_quanta[7:0];
902
            default :
903
              tx_byte = 8'h00;
904
          endcase // case (mux_select)
905
        end
906
      else if (!fcs_active && !set_pad_byte)
907
        begin
908
          //primary data flow
909
          tx_byte = tx_fsm_dt_reg[7:0];
910
//        $stop;
911
        end // if (!fcs_active)
912
      else if (fcs_active)
913
        begin
914
          tx_byte = tc2tx_fcs[7:0];
915
          case (fcs_mux_select)
916
            3'd0 :
917
              tx_byte = tc2tx_fcs[7:0];
918
            3'd1 :
919
              tx_byte = tc2tx_fcs[15:8];
920
            3'd2 :
921
              tx_byte = tc2tx_fcs[23:16];
922
            default :
923
              begin
924
                if (send_bad_fcs)
925
                  tx_byte = {!tc2tx_fcs[31], tc2tx_fcs[30:24]};
926
                else
927
                  tx_byte = tc2tx_fcs[31:24];
928
              end // case: 3'd7
929
          endcase // case (mux_select)
930
        end // else: !if(!fcs_active)
931
      else if (set_pad_byte)
932
        tx_byte = 8'd0;
933
      else
934
        tx_byte = 8'd0;
935
    end // always @ (fcs_active or app_tx_dt_in or tc2tx_fcs or mux_select...
936
 
937
  //generate fcs computation enable. One cycle after the
938
  //strt_preamble the tx_byte is stable and a cycle after the
939
  //mi2tx_byte_ack also a new byte is stable
940
  always @(posedge tx_clk or negedge tx_reset_n)
941
    begin
942
      if (!tx_reset_n)
943
        gen_tx_crc <= 1'b0;
944
      else
945
        begin
946
          if (fcs_active || strt_fcs)
947
            gen_tx_crc <= 1'b0;
948
          else
949
            gen_tx_crc <= strt_preamble || mi2tx_byte_ack;
950
        end // else: !if(!tx_reset_n)
951
    end // always (posedge tx_clk or negedge tx_reset_n)
952
 
953
 
954
endmodule // tx_fsm

powered by: WebSVN 2.1.0

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