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

Subversion Repositories ethernet_tri_mode

[/] [ethernet_tri_mode/] [trunk/] [rtl/] [verilog/] [MAC_tx/] [MAC_tx_Ctrl.v] - Rev 6

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

//////////////////////////////////////////////////////////////////////
////                                                              ////
////  MAC_tx_ctrl.v                                               ////
////                                                              ////
////  This file is part of the Ethernet IP core project           ////
////  http://www.opencores.org/projects.cgi/web/ethernet_tri_mode/////
////                                                              ////
////  Author(s):                                                  ////
////      - Jon Gao (gaojon@yahoo.com)                      	  ////
////                                                              ////
////                                                              ////
//////////////////////////////////////////////////////////////////////
////                                                              ////
//// Copyright (C) 2001 Authors                                   ////
////                                                              ////
//// This source file may be used and distributed without         ////
//// restriction provided that this copyright statement is not    ////
//// removed from the file and that any derivative work contains  ////
//// the original copyright notice and the associated disclaimer. ////
////                                                              ////
//// This source file is free software; you can redistribute it   ////
//// and/or modify it under the terms of the GNU Lesser General   ////
//// Public License as published by the Free Software Foundation; ////
//// either version 2.1 of the License, or (at your option) any   ////
//// later version.                                               ////
////                                                              ////
//// This source is distributed in the hope that it will be       ////
//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
//// PURPOSE.  See the GNU Lesser General Public License for more ////
//// details.                                                     ////
////                                                              ////
//// You should have received a copy of the GNU Lesser General    ////
//// Public License along with this source; if not, download it   ////
//// from http://www.opencores.org/lgpl.shtml                     ////
////                                                              ////
//////////////////////////////////////////////////////////////////////
//                                                                    
// CVS Revision History                                               
//                                                                    
// $Log: not supported by cvs2svn $
//
// Revision 1.1.1.1  2005/12/13 01:51:45  Administrator
// no message
//                                           
 
module MAC_tx_ctrl (  
Reset	       		,
Clk	                ,
//CRC_gen Interface  
CRC_init	        ,
Frame_data	        ,
Data_en	            ,
CRC_rd				,
CRC_end				,
CRC_out	            ,
//Ramdon_gen interfac
Random_init	        ,
RetryCnt	        ,
Random_time_meet	,
//flow control      
pause_apply	        ,
pause_quanta_sub	,
xoff_gen	        ,
xoff_gen_complete	,
xon_gen	            ,
xon_gen_complete	,
//MAC_tx_FF          
Fifo_data	 		,
Fifo_rd	        	,
Fifo_eop			,
Fifo_da				,
Fifo_rd_finish		,
Fifo_rd_retry		,
Fifo_ra				,
Fifo_data_err_empty	,
Fifo_data_err_full	,
//RMII               
TxD	    			,
TxEn	            ,
CRS					, 
//MAC_tx_addr_add   
MAC_tx_addr_rd	    ,
MAC_tx_addr_data	,
MAC_tx_addr_init    ,
//RMON               
Tx_pkt_type_rmon	,
Tx_pkt_length_rmon	,
Tx_apply_rmon	    ,
Tx_pkt_err_type_rmon,
//CPU  
pause_frame_send_en	,
pause_quanta_set	,              
MAC_tx_add_en		,  
FullDuplex         	,
MaxRetry	        ,
IFGset			
);
 
input			Reset	       		;
input			Clk	                ;
				//CRC_gen Interface 
output			CRC_init	        ;
output[7:0]		Frame_data	        ;
output			Data_en	            ;
output			CRC_rd				;
input			CRC_end				;
input[7:0]		CRC_out	            ;
				//Ramdon_gen interface
output			Random_init	        ;
output[3:0]		RetryCnt	        ;
input			Random_time_meet	;//levle hight indicate random time passed away
				//flow control
input			pause_apply	        ;
output			pause_quanta_sub	;
input			xoff_gen	        ;
output			xoff_gen_complete	;
input			xon_gen	            ;
output			xon_gen_complete	;				
				//MAC_rx_FF
input[7:0]		Fifo_data	 		;
output			Fifo_rd	        	;
input			Fifo_eop			;
input			Fifo_da				;
output			Fifo_rd_finish		;
output			Fifo_rd_retry		;
input			Fifo_ra				;
input			Fifo_data_err_empty	;
input			Fifo_data_err_full	;
				//RMII
output[7:0]		TxD	    			;
output			TxEn	            ;   
input			CRS					;
				//MAC_tx_addr_add
output			MAC_tx_addr_init    ;
output			MAC_tx_addr_rd	    ;
input[7:0]		MAC_tx_addr_data	;
				//RMON
output[2:0]		Tx_pkt_type_rmon	;
output[15:0]	Tx_pkt_length_rmon	;
output			Tx_apply_rmon	    ;
output[2:0]		Tx_pkt_err_type_rmon;	
				//CPU
input			pause_frame_send_en	;				
input[15:0]		pause_quanta_set	;
input			MAC_tx_add_en		;				
input			FullDuplex         	;
input[3:0]		MaxRetry	        ;
input[5:0]		IFGset				;
//******************************************************************************		
//internal signals                                                              
//******************************************************************************   
parameter		StateIdle      		=4'd00;
parameter		StatePreamble   	=4'd01;
parameter		StateSFD	    	=4'd02;
parameter		StateData       	=4'd03;
parameter		StatePause      	=4'd04;
parameter		StatePAD        	=4'd05;
parameter		StateFCS        	=4'd06;
parameter		StateIFG        	=4'd07;
parameter		StateJam        	=4'd08;
parameter		StateBackOff    	=4'd09;
parameter		StateJamDrop    	=4'd10;
parameter		StateFFEmptyDrop	=4'd11;
parameter		StateSwitchNext 	=4'd12;
parameter		StateDefer      	=4'd13;
parameter		StateSendPauseFrame	=4'd14;
 
reg[3:0]		Current_state   /*synthesis syn_keep=1 */;
reg[3:0]		Next_state;
reg[5:0]		IFG_counter;
reg[4:0]		Preamble_counter;//
reg[7:0]		TxD_tmp				;	
reg				TxEn_tmp			;	
reg[15:0]		Tx_pkt_length_rmon	;
reg				Tx_apply_rmon	    ;
reg[2:0]		Tx_pkt_err_type_rmon;	
reg[3:0]		RetryCnt			;
reg				Random_init			;
reg				Fifo_rd_finish		;
reg				Fifo_rd_retry		;
reg[7:0]		TxD					;	
reg				TxEn				;	
reg				CRC_init	        ;
reg				Data_en	            ;
reg				CRC_rd				;
reg				Fifo_rd				;
reg				MAC_tx_addr_rd	    ;
reg				MAC_header_slot		;
reg				MAC_header_slot_tmp	;
reg[2:0]		Tx_pkt_type_rmon	;
wire			Collision	        ; 
reg				MAC_tx_addr_init    ;
reg				Src_MAC_ptr			;
reg[7:0]		IPLengthCounter		;//for pad append
reg[1:0]		PADCounter			;
reg[7:0]		JamCounter			;
reg				PktDrpEvenPtr		;
reg[7:0]		pause_counter		;
reg				pause_quanta_sub	;
reg				pause_frame_send_en_dl1	;				
reg[15:0]		pause_quanta_set_dl1	;
reg	[4:0]		send_pause_frame_counter	;
reg				xoff_gen_reg		;			    
reg				xon_gen_reg		;
reg				xoff_gen_complete	;
reg				xon_gen_complete	;
//******************************************************************************    
//boundery signal processing                                                             
//****************************************************************************** 
always @(posedge Clk or posedge Reset)
	if (Reset)
		begin  
		pause_frame_send_en_dl1			<=0;
		pause_quanta_set_dl1	        <=0;
		end
	else
		begin  
		pause_frame_send_en_dl1			<=pause_frame_send_en	;
		pause_quanta_set_dl1	        <=pause_quanta_set		;
		end		
 
//******************************************************************************    
//state machine                                                             
//****************************************************************************** 
assign Collision=TxEn&CRS;
 
always @(posedge Clk or posedge Reset)
	if (Reset)
		send_pause_frame_counter	<=0;
	else if(Current_state!=StateSendPauseFrame)
		send_pause_frame_counter	<=0;
	else
		send_pause_frame_counter	<=send_pause_frame_counter +1;
 
always @(posedge Clk or posedge Reset)
	if (Reset)
		pause_counter	<=0;
	else if (Current_state!=StatePause)
		pause_counter	<=0;
	else 
		pause_counter	<=pause_counter+1;
 
always @(posedge Clk or posedge Reset)
	if (Reset)
		IPLengthCounter		<=0;
	else if (Current_state==StateSwitchNext)
		IPLengthCounter		<=0;	
	else if (IPLengthCounter!=8'hff&&(Current_state==StateData||Current_state==StatePAD))
		IPLengthCounter		<=IPLengthCounter+1;
 
always @(posedge Clk or posedge Reset)
	if (Reset)
		PADCounter		<=0;
	else if (Current_state!=StatePAD)
		PADCounter		<=0;
	else
		PADCounter		<=PADCounter+1;
 
always @(posedge Clk or posedge Reset)
	if (Reset)
		Current_state		<=StateDefer;
	else 
		Current_state		<=Next_state;    
 
always @ (*)
		case (Current_state)   
			StateDefer:
				if ((FullDuplex)||(!FullDuplex&&!CRS))
					Next_state=StateIFG;
				else
					Next_state=Current_state;	
			StateIFG:
				if (!FullDuplex&&CRS)
					Next_state=StateDefer;
				else if ((FullDuplex&&IFG_counter==IFGset-4)||(!FullDuplex&&!CRS&&IFG_counter==IFGset-4))//去掉一些耽搁的时间
					Next_state=StateIdle;
				else
					Next_state=Current_state;			
			StateIdle:
				if (!FullDuplex&&CRS)
					Next_state=StateDefer;
				else if (pause_apply)
					Next_state=StatePause;			
				else if ((FullDuplex&&Fifo_ra)||(!FullDuplex&&!CRS&&Fifo_ra)||(pause_frame_send_en_dl1&&(xoff_gen_reg||xon_gen_reg)))
					Next_state=StatePreamble;
				else
					Next_state=Current_state;	
			StatePause:
				if (pause_counter==512/8)
					Next_state=StateDefer;
				else
					Next_state=Current_state;				
			StatePreamble:
				if (!FullDuplex&&Collision)
					Next_state=StateJam;
				else if ((FullDuplex&&Preamble_counter==7)||(!FullDuplex&&!Collision&&Preamble_counter==7))
					Next_state=StateSFD;
				else
					Next_state=Current_state;
			StateSFD:
				if (!FullDuplex&&Collision)
					Next_state=StateJam;
				else if (pause_frame_send_en_dl1&&(xoff_gen_reg||xon_gen_reg))
					Next_state=StateSendPauseFrame;
				else 
					Next_state=StateData;
			StateSendPauseFrame:
				if (send_pause_frame_counter==19)
					Next_state=StatePAD;
				else
					Next_state=Current_state;
			StateData:
				if (!FullDuplex&&Collision)
					Next_state=StateJam;
				else if (Fifo_data_err_empty)
					Next_state=StateFFEmptyDrop;				
				else if (Fifo_eop&&IPLengthCounter>=59)//IP+MAC+TYPE=60 ,start from 0
					Next_state=StateFCS;
				else if (Fifo_eop)
					Next_state=StatePAD;
				else 
					Next_state=StateData;		
			StatePAD:
				if (!FullDuplex&&Collision)
					Next_state=StateJam; 
				else if (IPLengthCounter>=59)
					Next_state=StateFCS;		
				else 
					Next_state=Current_state;
			StateJam:
				if (RetryCnt<=MaxRetry&&JamCounter==16) 
					Next_state=StateBackOff;
				else if (RetryCnt>MaxRetry)
					Next_state=StateJamDrop;
				else
					Next_state=Current_state;
			StateBackOff:
				if (Random_time_meet)
					Next_state	=StateDefer;
				else 
					Next_state	=Current_state;
			StateFCS:
				if (!FullDuplex&&Collision)
					Next_state	=StateJam;
				else if (pause_frame_send_en_dl1&&(xoff_gen_reg||xon_gen_reg))
					Next_state	=StateDefer;
				else if (CRC_end)
					Next_state	=StateSwitchNext;
				else
					Next_state	=Current_state;
			StateFFEmptyDrop:
				if (Fifo_eop)
					Next_state	=StateSwitchNext;
				else
					Next_state	=Current_state;				
			StateJamDrop:
				if (Fifo_eop)
					Next_state	=StateSwitchNext;
				else
					Next_state	=Current_state;
			StateSwitchNext:
					Next_state	=StateDefer;			
			default:
				Next_state	=StateDefer;
		endcase
 
 
 
always @ (posedge Clk or posedge Reset)
	if (Reset)
		JamCounter		<=0;
	else if (Current_state!=StateJam)
		JamCounter		<=0;
	else if (Current_state==StateJam)
		JamCounter		<=JamCounter+1;
 
 
always @ (posedge Clk or posedge Reset)
	if (Reset)
		RetryCnt		<=0;
	else if (Current_state==StateSwitchNext)
		RetryCnt		<=0;
	else if (Current_state==StateJam&&Next_state==StateBackOff)
		RetryCnt		<=RetryCnt + 1;
 
always @ (posedge Clk or posedge Reset)
	if (Reset)
		IFG_counter		<=0;
	else if (Current_state!=StateIFG)
		IFG_counter		<=0;
	else 
		IFG_counter		<=IFG_counter + 1;
 
always @ (posedge Clk or posedge Reset)
	if (Reset)
		Preamble_counter	<=0;
	else if (Current_state!=StatePreamble)
		Preamble_counter	<=0;
	else
		Preamble_counter	<=Preamble_counter+ 1;
 
always @ (posedge Clk or posedge Reset)
	if (Reset)		
		PktDrpEvenPtr		<=0;
	else if(Current_state==StateJamDrop||Current_state==StateFFEmptyDrop)
		PktDrpEvenPtr		<=~PktDrpEvenPtr;
//******************************************************************************    
//generate output signals                                                           
//****************************************************************************** 
//CRC related
always @(Current_state)
	if (Current_state==StateSFD)
		CRC_init	=1;
	else
		CRC_init	=0;
 
assign Frame_data=TxD_tmp;
 
always @(Current_state)
	if (Current_state==StateData||Current_state==StatePAD)
		Data_en		=1;
	else
		Data_en		=0;
 
always @(Current_state)
	if (Current_state==StateFCS)
		CRC_rd		=1;
	else
		CRC_rd		=0;		
 
//Ramdon_gen interface
always @(Current_state or Next_state)
	if (Current_state==StateJam&&Next_state==StateBackOff)
		Random_init	=1;
	else
		Random_init	=0;	
 
//MAC_rx_FF
//data have one cycle delay after fifo read signals  
always @ (*)
	if (Current_state==StateData ||
		Current_state==StateSFD&&!(pause_frame_send_en_dl1&&(xoff_gen_reg||xon_gen_reg))  ||
		Current_state==StateJamDrop&&PktDrpEvenPtr||
		Current_state==StateFFEmptyDrop&&PktDrpEvenPtr )
		Fifo_rd		=1;
	else
		Fifo_rd		=0;	
 
always @ (Current_state)
	if (Current_state==StateSwitchNext)		
		Fifo_rd_finish	=1;
	else
		Fifo_rd_finish	=0;
 
always @ (Current_state)
	if (Current_state==StateJam)		
		Fifo_rd_retry	=1;
	else
		Fifo_rd_retry	=0;		
//RMII
always @(Current_state)
	if (Current_state==StatePreamble||Current_state==StateSFD||
		Current_state==StateData||
		Current_state==StateFCS||Current_state==StatePAD||Current_state==StateJam)
		TxEn_tmp	=1;
	else
		TxEn_tmp	=0;
 
//gen txd data		
always @(*)
	case (Current_state)
		StatePreamble:
			TxD_tmp	=8'h55;
		StateSFD:
			TxD_tmp	=8'hd5;
		StateData:
			if (Src_MAC_ptr&&MAC_tx_add_en)       
				TxD_tmp	=MAC_tx_addr_data;
			else
				TxD_tmp	=Fifo_data;
		StateSendPauseFrame:
			if (Src_MAC_ptr)       
				TxD_tmp	=MAC_tx_addr_data;
			else 
				case (send_pause_frame_counter)
					5'd0:	TxD_tmp	=8'h01;
					5'd1:	TxD_tmp	=8'h80;
					5'd2:	TxD_tmp	=8'hc2;
					5'd3:	TxD_tmp	=8'h00;
					5'd4:	TxD_tmp	=8'h00;
					5'd5:	TxD_tmp	=8'h01;
					5'd12:	TxD_tmp	=8'h88;//type
					5'd13:	TxD_tmp	=8'h08;//
					5'd14:	TxD_tmp	=8'h00;//opcode
					5'd15:	TxD_tmp	=8'h01;
					5'd16:	TxD_tmp	=pause_quanta_set_dl1[15:8];
					5'd17:	TxD_tmp	=pause_quanta_set_dl1[7:0];
					default:TxD_tmp	=0;
				endcase
 
		StatePAD:
				TxD_tmp	=8'h00; 
		StateJam:
				TxD_tmp	=8'h01; //jam sequence
		StateFCS:
			TxD_tmp	=CRC_out;
		default:
			TxD_tmp	=2'b0;
	endcase
always @ (posedge Clk or posedge Reset)
	if (Reset)
		begin
		TxD		<=0;
		TxEn	<=0;
		end
	else
		begin
		TxD		<=TxD_tmp;
		TxEn	<=TxEn_tmp;
		end		
//RMON
 
 
always @ (posedge Clk or posedge Reset)
	if (Reset)
		Tx_pkt_length_rmon		<=0;
	else if (Current_state==StateSFD)
		Tx_pkt_length_rmon		<=0;
	else if (Current_state==StateData)
		Tx_pkt_length_rmon		<=Tx_pkt_length_rmon+1;
 
always @ (posedge Clk or posedge Reset)
	if (Reset)
		Tx_apply_rmon	    <=0;
	else if ((Fifo_eop&&Current_state==StateJamDrop)||
			 (Fifo_eop&&Current_state==StateFFEmptyDrop)||
			 CRC_end)
		Tx_apply_rmon	    <=1;
	else
		Tx_apply_rmon	    <=0;
 
always @ (posedge Clk or posedge Reset)
	if (Reset)
		Tx_pkt_err_type_rmon	<=0;	
	else if(Fifo_eop&&Current_state==StateJamDrop)
		Tx_pkt_err_type_rmon	<=3'b001;//
	else if(Fifo_eop&&Current_state==StateFFEmptyDrop)
		Tx_pkt_err_type_rmon	<=3'b010;//underflow
	else if(Fifo_eop&&Fifo_data_err_full)
		Tx_pkt_err_type_rmon	<=3'b011;//overflow
	else if(CRC_end)
		Tx_pkt_err_type_rmon	<=3'b100;
 
always @ (posedge Clk or posedge Reset)
	if (Reset)
		MAC_header_slot_tmp	<=0;
	else if(Current_state==StateSFD&&Next_state==StateData)
		MAC_header_slot_tmp	<=0;	
	else
		MAC_header_slot_tmp	<=0;
 
always @ (posedge Clk or posedge Reset)
	if (Reset)
		MAC_header_slot		<=0;
	else 
		MAC_header_slot		<=MAC_header_slot_tmp;
 
always @ (posedge Clk or posedge Reset)
	if (Reset)
		Tx_pkt_type_rmon	<=0;
	else if (Current_state==StateSendPauseFrame)
		Tx_pkt_type_rmon	<=3'b100;
	else if(MAC_header_slot)
		Tx_pkt_type_rmon	<={1'b0,TxD_tmp};
 
always @(Tx_pkt_length_rmon)
	if (Tx_pkt_length_rmon>=6&&Tx_pkt_length_rmon<=11)
		Src_MAC_ptr			=1;
	else
		Src_MAC_ptr			=0;
 
//MAC_tx_addr_add  
always @ (Tx_pkt_length_rmon or Fifo_rd or Src_MAC_ptr)
	if (Src_MAC_ptr&&(MAC_tx_add_en||Current_state==StateSendPauseFrame))
		MAC_tx_addr_rd	=1;
	else
		MAC_tx_addr_rd	=0;
 
always @ (Tx_pkt_length_rmon or Fifo_rd)
	if ((Tx_pkt_length_rmon==5)&&Fifo_rd)
		MAC_tx_addr_init=1;
	else
		MAC_tx_addr_init=0;
 
//flow control
always @ (posedge Clk or posedge Reset)
	if (Reset)
		pause_quanta_sub	<=0;
	else if(pause_counter==512/8)
		pause_quanta_sub	<=1;
	else
		pause_quanta_sub	<=0;
 
 
always @ (posedge Clk or posedge Reset)
	if (Reset) 
		begin
		xoff_gen_reg		<=0;
		xon_gen_reg	        <=0;
		end	
	else if (Current_state==StateDefer)
		begin
		xoff_gen_reg	     <=xoff_gen;
		xon_gen_reg	         <=xon_gen;
		end			
 
always @ (posedge Clk or posedge Reset)
	if (Reset) 
		xoff_gen_complete	<=0;
	else if(Current_state==StateDefer&&xoff_gen_reg)
		xoff_gen_complete	<=1;
	else
		xoff_gen_complete	<=0;
 
 
always @ (posedge Clk or posedge Reset)
	if (Reset) 
		xon_gen_complete	<=0;
	else if(Current_state==StateDefer&&xon_gen_reg)
		xon_gen_complete	<=1;
	else
		xon_gen_complete	<=0;
 
endmodule
 

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

powered by: WebSVN 2.1.0

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