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 37

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

powered by: WebSVN 2.1.0

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