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 76

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

powered by: WebSVN 2.1.0

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