1 //////////////////////////////////////////////////////////////////////
3 //// MAC_tx_ctrl.v ////
5 //// This file is part of the Ethernet IP core project ////
6 //// http://www.opencores.org/projects.cgi/web/ethernet_tri_mode/////
9 //// - Jon Gao (gaojon@yahoo.com) ////
12 //////////////////////////////////////////////////////////////////////
14 //// Copyright (C) 2001 Authors ////
16 //// This source file may be used and distributed without ////
17 //// restriction provided that this copyright statement is not ////
18 //// removed from the file and that any derivative work contains ////
19 //// the original copyright notice and the associated disclaimer. ////
21 //// This source file is free software; you can redistribute it ////
22 //// and/or modify it under the terms of the GNU Lesser General ////
23 //// Public License as published by the Free Software Foundation; ////
24 //// either version 2.1 of the License, or (at your option) any ////
25 //// later version. ////
27 //// This source is distributed in the hope that it will be ////
28 //// useful, but WITHOUT ANY WARRANTY; without even the implied ////
29 //// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
30 //// PURPOSE. See the GNU Lesser General Public License for more ////
33 //// You should have received a copy of the GNU Lesser General ////
34 //// Public License along with this source; if not, download it ////
35 //// from http://www.opencores.org/lgpl.shtml ////
37 //////////////////////////////////////////////////////////////////////
39 // CVS Revision History
41 // $Log: MAC_tx_Ctrl.v,v $
42 // Revision 1.4 2006/06/25 04:58:56 maverickist
45 // Revision 1.3 2006/01/19 14:07:54 maverickist
46 // verification is complete.
48 // Revision 1.3 2005/12/16 06:44:17 Administrator
49 // replaced tab with space.
50 // passed 9.6k length frame test.
52 // Revision 1.2 2005/12/13 12:15:38 Administrator
55 // Revision 1.1.1.1 2005/12/13 01:51:45 Administrator
102 Tx_pkt_err_type_rmon,
104 pause_frame_send_en ,
116 output [7:0] Frame_data ;
120 input [7:0] CRC_out ;
121 //Ramdon_gen interface
123 output [3:0] RetryCnt ;
124 input Random_time_meet ;//levle hight indicate random time passed away
127 output pause_quanta_sub ;
129 output xoff_gen_complete ;
131 output xon_gen_complete ;
133 input [7:0] Fifo_data ;
137 output Fifo_rd_finish ;
138 output Fifo_rd_retry ;
140 input Fifo_data_err_empty ;
141 input Fifo_data_err_full ;
147 output MAC_tx_addr_init ;
148 output MAC_tx_addr_rd ;
149 input [7:0] MAC_tx_addr_data ;
151 output [2:0] Tx_pkt_type_rmon ;
152 output [15:0] Tx_pkt_length_rmon ;
153 output Tx_apply_rmon ;
154 output [2:0] Tx_pkt_err_type_rmon;
156 input pause_frame_send_en ;
157 input [15:0] pause_quanta_set ;
158 input MAC_tx_add_en ;
160 input [3:0] MaxRetry ;
162 //******************************************************************************
164 //******************************************************************************
165 parameter StateIdle =4'd00;
166 parameter StatePreamble =4'd01;
167 parameter StateSFD =4'd02;
168 parameter StateData =4'd03;
169 parameter StatePause =4'd04;
170 parameter StatePAD =4'd05;
171 parameter StateFCS =4'd06;
172 parameter StateIFG =4'd07;
173 parameter StateJam =4'd08;
174 parameter StateBackOff =4'd09;
175 parameter StateJamDrop =4'd10;
176 parameter StateFFEmptyDrop =4'd11;
177 parameter StateSwitchNext =4'd12;
178 parameter StateDefer =4'd13;
179 parameter StateSendPauseFrame =4'd14;
181 reg [3:0] Current_state /*synthesis syn_keep=1 */;
182 reg [3:0] Next_state;
183 reg [5:0] IFG_counter;
184 reg [4:0] Preamble_counter;//
187 reg [15:0] Tx_pkt_length_rmon ;
189 reg Tx_apply_rmon_tmp ;
190 reg Tx_apply_rmon_tmp_pl1;
191 reg [2:0] Tx_pkt_err_type_rmon;
203 reg MAC_header_slot ;
204 reg MAC_header_slot_tmp ;
205 reg [2:0] Tx_pkt_type_rmon ;
207 reg MAC_tx_addr_init ;
209 reg [7:0] IPLengthCounter ;//for pad append
210 reg [1:0] PADCounter ;
211 reg [7:0] JamCounter ;
213 reg [7:0] pause_counter ;
214 reg pause_quanta_sub ;
215 reg pause_frame_send_en_dl1 ;
216 reg [15:0] pause_quanta_set_dl1 ;
217 reg xoff_gen_complete ;
218 reg xon_gen_complete ;
219 //******************************************************************************
220 //boundery signal processing
221 //******************************************************************************
222 always @(posedge Clk or posedge Reset)
225 pause_frame_send_en_dl1 <=0;
226 pause_quanta_set_dl1 <=0;
230 pause_frame_send_en_dl1 <=pause_frame_send_en ;
231 pause_quanta_set_dl1 <=pause_quanta_set ;
233 //******************************************************************************
235 //******************************************************************************
236 assign Collision=TxEn&CRS;
238 always @(posedge Clk or posedge Reset)
241 else if (Current_state!=StatePause)
244 pause_counter <=pause_counter+1;
246 always @(posedge Clk or posedge Reset)
249 else if (Current_state==StateDefer)
251 else if (IPLengthCounter!=8'hff&&(Current_state==StateData||Current_state==StateSendPauseFrame||Current_state==StatePAD))
252 IPLengthCounter <=IPLengthCounter+1;
254 always @(posedge Clk or posedge Reset)
257 else if (Current_state!=StatePAD)
260 PADCounter <=PADCounter+1;
262 always @(posedge Clk or posedge Reset)
264 Current_state <=StateDefer;
266 Current_state <=Next_state;
271 if ((FullDuplex)||(!FullDuplex&&!CRS))
274 Next_state=Current_state;
276 if (!FullDuplex&&CRS)
277 Next_state=StateDefer;
278 else if ((FullDuplex&&IFG_counter==IFGset-4)||(!FullDuplex&&!CRS&&IFG_counter==IFGset-4))//remove some additional time
279 Next_state=StateIdle;
281 Next_state=Current_state;
283 if (!FullDuplex&&CRS)
284 Next_state=StateDefer;
285 else if (pause_apply)
286 Next_state=StatePause;
287 else if ((FullDuplex&&Fifo_ra)||(!FullDuplex&&!CRS&&Fifo_ra)||(pause_frame_send_en_dl1&&(xoff_gen||xon_gen)))
288 Next_state=StatePreamble;
290 Next_state=Current_state;
292 if (pause_counter==512/8)
293 Next_state=StateDefer;
295 Next_state=Current_state;
297 if (!FullDuplex&&Collision)
299 else if ((FullDuplex&&Preamble_counter==6)||(!FullDuplex&&!Collision&&Preamble_counter==6))
302 Next_state=Current_state;
304 if (!FullDuplex&&Collision)
306 else if (pause_frame_send_en_dl1&&(xoff_gen||xon_gen))
307 Next_state=StateSendPauseFrame;
309 Next_state=StateData;
311 if (IPLengthCounter==17)
314 Next_state=Current_state;
316 if (!FullDuplex&&Collision)
318 else if (Fifo_data_err_empty)
319 Next_state=StateFFEmptyDrop;
320 else if (Fifo_eop&&IPLengthCounter>=59)//IP+MAC+TYPE=60 ,start from 0
325 Next_state=StateData;
327 if (!FullDuplex&&Collision)
329 else if (IPLengthCounter>=59)
332 Next_state=Current_state;
334 if (RetryCnt<=MaxRetry&&JamCounter==16)
335 Next_state=StateBackOff;
336 else if (RetryCnt>MaxRetry)
337 Next_state=StateJamDrop;
339 Next_state=Current_state;
341 if (Random_time_meet)
342 Next_state =StateDefer;
344 Next_state =Current_state;
346 if (!FullDuplex&&Collision)
347 Next_state =StateJam;
349 Next_state =StateSwitchNext;
351 Next_state =Current_state;
354 Next_state =StateSwitchNext;
356 Next_state =Current_state;
359 Next_state =StateSwitchNext;
361 Next_state =Current_state;
363 Next_state =StateDefer;
365 Next_state =StateDefer;
370 always @ (posedge Clk or posedge Reset)
373 else if (Current_state!=StateJam)
375 else if (Current_state==StateJam)
376 JamCounter <=JamCounter+1;
379 always @ (posedge Clk or posedge Reset)
382 else if (Current_state==StateSwitchNext)
384 else if (Current_state==StateJam&&Next_state==StateBackOff)
385 RetryCnt <=RetryCnt + 1;
387 always @ (posedge Clk or posedge Reset)
390 else if (Current_state!=StateIFG)
393 IFG_counter <=IFG_counter + 1;
395 always @ (posedge Clk or posedge Reset)
397 Preamble_counter <=0;
398 else if (Current_state!=StatePreamble)
399 Preamble_counter <=0;
401 Preamble_counter <=Preamble_counter+ 1;
403 always @ (posedge Clk or posedge Reset)
406 else if(Current_state==StateJamDrop||Current_state==StateFFEmptyDrop)
407 PktDrpEvenPtr <=~PktDrpEvenPtr;
408 //******************************************************************************
409 //generate output signals
410 //******************************************************************************
412 always @(Current_state)
413 if (Current_state==StateSFD)
418 assign Frame_data=TxD_tmp;
420 always @(Current_state)
421 if (Current_state==StateData||Current_state==StateSendPauseFrame||Current_state==StatePAD)
426 always @(Current_state)
427 if (Current_state==StateFCS)
432 //Ramdon_gen interface
433 always @(Current_state or Next_state)
434 if (Current_state==StateJam&&Next_state==StateBackOff)
440 //data have one cycle delay after fifo read signals
442 if (Current_state==StateData ||
443 Current_state==StateSFD&&!(pause_frame_send_en_dl1&&(xoff_gen||xon_gen)) ||
444 Current_state==StateJamDrop&&PktDrpEvenPtr||
445 Current_state==StateFFEmptyDrop&&PktDrpEvenPtr )
450 always @ (Current_state)
451 if (Current_state==StateSwitchNext)
456 always @ (Current_state)
457 if (Current_state==StateJam)
462 always @(Current_state)
463 if (Current_state==StatePreamble||Current_state==StateSFD||
464 Current_state==StateData||Current_state==StateSendPauseFrame||
465 Current_state==StateFCS||Current_state==StatePAD||Current_state==StateJam)
478 if (Src_MAC_ptr&&MAC_tx_add_en)
479 TxD_tmp =MAC_tx_addr_data;
483 if (Src_MAC_ptr&&MAC_tx_add_en)
484 TxD_tmp =MAC_tx_addr_data;
486 case (IPLengthCounter)
487 7'd0: TxD_tmp =8'h01;
488 7'd1: TxD_tmp =8'h80;
489 7'd2: TxD_tmp =8'hc2;
490 7'd3: TxD_tmp =8'h00;
491 7'd4: TxD_tmp =8'h00;
492 7'd5: TxD_tmp =8'h01;
493 7'd12: TxD_tmp =8'h88;//type
494 7'd13: TxD_tmp =8'h08;//
495 7'd14: TxD_tmp =8'h00;//opcode
496 7'd15: TxD_tmp =8'h01;
497 7'd16: TxD_tmp =xon_gen?8'b0:pause_quanta_set_dl1[15:8];
498 7'd17: TxD_tmp =xon_gen?8'b0:pause_quanta_set_dl1[7:0];
499 // 7'd60: TxD_tmp =8'h26;
500 // 7'd61: TxD_tmp =8'h6b;
501 // 7'd62: TxD_tmp =8'hae;
502 // 7'd63: TxD_tmp =8'h0a;
509 TxD_tmp =8'h01; //jam sequence
515 always @ (posedge Clk or posedge Reset)
529 always @ (posedge Clk or posedge Reset)
531 Tx_pkt_length_rmon <=0;
532 else if (Current_state==StateSFD)
533 Tx_pkt_length_rmon <=0;
534 else if (Current_state==StateData||Current_state==StateSendPauseFrame||Current_state==StatePAD||Current_state==StateFCS)
535 Tx_pkt_length_rmon <=Tx_pkt_length_rmon+1;
537 always @ (posedge Clk or posedge Reset)
539 Tx_apply_rmon_tmp <=0;
540 else if ((Fifo_eop&&Current_state==StateJamDrop)||
541 (Fifo_eop&&Current_state==StateFFEmptyDrop)||
543 Tx_apply_rmon_tmp <=1;
545 Tx_apply_rmon_tmp <=0;
547 always @ (posedge Clk or posedge Reset)
549 Tx_apply_rmon_tmp_pl1 <=0;
551 Tx_apply_rmon_tmp_pl1 <=Tx_apply_rmon_tmp;
553 always @ (posedge Clk or posedge Reset)
556 else if ((Fifo_eop&&Current_state==StateJamDrop)||
557 (Fifo_eop&&Current_state==StateFFEmptyDrop)||
560 else if (Tx_apply_rmon_tmp_pl1)
563 always @ (posedge Clk or posedge Reset)
565 Tx_pkt_err_type_rmon <=0;
566 else if(Fifo_eop&&Current_state==StateJamDrop)
567 Tx_pkt_err_type_rmon <=3'b001;//
568 else if(Fifo_eop&&Current_state==StateFFEmptyDrop)
569 Tx_pkt_err_type_rmon <=3'b010;//underflow
570 else if(Fifo_eop&&Fifo_data_err_full)
571 Tx_pkt_err_type_rmon <=3'b011;//overflow
573 Tx_pkt_err_type_rmon <=3'b100;//normal
575 always @ (posedge Clk or posedge Reset)
577 MAC_header_slot_tmp <=0;
578 else if(Current_state==StateSFD&&Next_state==StateData)
579 MAC_header_slot_tmp <=1;
581 MAC_header_slot_tmp <=0;
583 always @ (posedge Clk or posedge Reset)
587 MAC_header_slot <=MAC_header_slot_tmp;
589 always @ (posedge Clk or posedge Reset)
591 Tx_pkt_type_rmon <=0;
592 else if (Current_state==StateSendPauseFrame)
593 Tx_pkt_type_rmon <=3'b100;
594 else if(MAC_header_slot)
595 Tx_pkt_type_rmon <={1'b0,TxD[7:6]};
598 always @(Tx_pkt_length_rmon)
599 if (Tx_pkt_length_rmon>=6&&Tx_pkt_length_rmon<=11)
605 always @ (posedge Clk or posedge Reset)
608 else if ((Tx_pkt_length_rmon>=4&&Tx_pkt_length_rmon<=9)&&(MAC_tx_add_en||Current_state==StateSendPauseFrame))
613 always @ (Tx_pkt_length_rmon or Fifo_rd)
614 if ((Tx_pkt_length_rmon==3)&&Fifo_rd)
620 always @ (posedge Clk or posedge Reset)
622 pause_quanta_sub <=0;
623 else if(pause_counter==512/8)
624 pause_quanta_sub <=1;
626 pause_quanta_sub <=0;
629 always @ (posedge Clk or posedge Reset)
631 xoff_gen_complete <=0;
632 else if(Current_state==StateDefer&&xoff_gen)
633 xoff_gen_complete <=1;
635 xoff_gen_complete <=0;
638 always @ (posedge Clk or posedge Reset)
640 xon_gen_complete <=0;
641 else if(Current_state==StateDefer&&xon_gen)
642 xon_gen_complete <=1;
644 xon_gen_complete <=0;