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 77

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

powered by: WebSVN 2.1.0

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