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_rx/] [MAC_rx_ctrl.v] - Rev 6

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

//////////////////////////////////////////////////////////////////////
////                                                              ////
////  MAC_rx_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_rx_ctrl (
Reset	,                                     
Clk	    ,                                     
 
//RMII interface                                    
MCrs_dv	,		//
MRxD	,		//  
MRxErr	,		//  
//CRC_chk interface                                 
CRC_en    ,                                 
CRC_init  ,
CRC_err  ,                      
//MAC_rx_add_chk interface                          
MAC_add_en			,                         
MAC_rx_add_chk_err	,   
//broadcast_filter     
broadcast_ptr	,      
broadcast_drop	,   
//flow_control signals      
pause_quanta		,       
pause_quanta_val	,       
//MAC_rx_FF interface                               
Fifo_data		,                             
Fifo_data_en	,                             
Fifo_data_err	,  
Fifo_data_end	,  
Fifo_full		,                          
//RMON interface                
Rx_pkt_type_rmon		,                    
Rx_pkt_length_rmon		,                     
Rx_apply_rmon	        ,                     
Rx_pkt_err_type_rmon	,                     
//CPU                                         
RX_IFG_SET	  ,
RX_MAX_LENGTH,
RX_MIN_LENGTH
 
);
 
input			Reset	;         
input			Clk	    ;         
				//RMII interface  
input			MCrs_dv	;		                                
input	[7:0]	MRxD	;		                                
input			MRxErr	;		                                
				//CRC_chk interface
output			CRC_en  ;       
output			CRC_init;       
input           CRC_err ;
				//MAC_rx_add_chk interface
output			MAC_add_en			;
input			MAC_rx_add_chk_err	;
				//broadcast_filter
output			broadcast_ptr	        ;
input			broadcast_drop	        ;
				//flow_control signals  
output	[15:0]	pause_quanta		;   
output			pause_quanta_val	;   
				//MAC_rx_FF interface
output	[7:0]	Fifo_data		;
output			Fifo_data_en	;
output			Fifo_data_err	;
output			Fifo_data_end	;
input			Fifo_full;
				//RMON interface
output	[15:0]	Rx_pkt_length_rmon		;
output			Rx_apply_rmon	        ;
output	[2:0]	Rx_pkt_err_type_rmon	;
output	[2:0]	Rx_pkt_type_rmon		;
				//CPU
input	[5:0]	RX_IFG_SET	  ;
input	[15:0]	RX_MAX_LENGTH 	;//	1518
input	[6:0]	RX_MIN_LENGTH	;//	64
 
//******************************************************************************
//internal signals
//******************************************************************************
parameter		State_idle			=4'd00;
parameter		State_preamble      =4'd01;
parameter		State_SFD           =4'd02;
parameter		State_data          =4'd03;
parameter		State_checkCRC      =4'd04;
parameter		State_OkEnd			=4'd07;
parameter		State_drop          =4'd08;
parameter		State_ErrEnd		=4'd09;
parameter		State_CRCErrEnd		=4'd10;
parameter		State_FFFullDrop	=4'd11;
parameter		State_FFFullErrEnd	=4'd12;
parameter		State_IFG           =4'd13;
 
parameter		Pause_idle          =4'd0;   
parameter		Pause_pre_syn       =4'd1;    
parameter		Pause_quanta_hi     =4'd2;   
parameter		Pause_quanta_lo     =4'd3;   
parameter		Pause_syn           =4'd4;   
 
reg	[3:0]		Current_state /* synthesis syn_keep=1 */;                          
reg	[3:0]		Next_state; 
reg	[3:0]		Pause_current /* synthesis syn_keep=1 */; 
reg	[3:0]		Pause_next;                             
reg	[5:0]		IFG_counter;   
reg				Crs_dv	;      
reg	[7:0]		RxD	;
reg	[7:0]		RxD_dl1	;
reg				RxErr	;
reg	[15:0]		Frame_length_counter;
reg				Too_long;
reg				Too_short;
reg				Fifo_data_en;
reg				Fifo_data_end;
reg				Fifo_data_err;
reg				CRC_en;
reg				CRC_init;
reg				Rx_apply_rmon;
reg	[2:0]		Rx_pkt_err_type_rmon;
reg				MAC_add_en;
reg	[2:0]		Rx_pkt_type_rmon;
reg	[7:0]		pause_quanta_h		;
reg	[15:0]		pause_quanta		;
reg				pause_quanta_val	;
reg				pause_quanta_val_tmp;
reg				pause_frame_ptr		;
reg				broadcast_ptr	        ;
//******************************************************************************
//delay signals                                                          
//******************************************************************************
 
always @ (posedge Reset or posedge Clk)                 
	if (Reset) 
		begin  
			Crs_dv		<=0;
			RxD			<=0;                                                            
            RxErr		<=0; 
        end
    else
    	begin  
			Crs_dv		<=MCrs_dv  	;
			RxD			<=MRxD		;                                                            
            RxErr   	<=MRxErr   	; 
        end
 
always @ (posedge Reset or posedge Clk)                 
	if (Reset) 
		RxD_dl1		<=0;
	else 
		RxD_dl1		<=RxD;
 
//******************************************************************************
//State_machine                                                           
//******************************************************************************
 
always @ (posedge Reset or posedge Clk)                 
	if (Reset)                                          
		Current_state	<=State_idle;                   
	else                                    
		Current_state	<=Next_state;                   
 
always @ (*)                                             
		case (Current_state)                            
			State_idle:
					if (Crs_dv&&RxD==8'h55)                
						Next_state	=State_preamble;    
					else                                
						Next_state	=Current_state;     
			State_preamble:                             
					if (!Crs_dv)                        
						Next_state	=State_ErrEnd;      
					else if (RxErr)                     
						Next_state	=State_drop;        
					else if (RxD==8'hd5)                 
						Next_state	=State_SFD;					
					else if (RxD==8'h55)                
						Next_state	=Current_state;     
					else                                
						Next_state	=State_drop;        
			State_SFD:                                  
					if (!Crs_dv)                        
						Next_state	=State_ErrEnd;      
					else if (RxErr)                     
						Next_state	=State_drop;        
					else                                
						Next_state	=State_data;       
			State_data:                                
					if (!Crs_dv&&!Too_short&&!Too_long)                        
						Next_state	=State_checkCRC;   
					else if (!Crs_dv&&(Too_short||Too_long))
						Next_state	=State_ErrEnd;
					else if (Fifo_full)
						Next_state	=State_FFFullErrEnd;
					else if (RxErr||MAC_rx_add_chk_err||Too_long||broadcast_drop)                     
						Next_state	=State_drop;        
					else                                
						Next_state	=State_data;	   
			State_checkCRC:
					 if (CRC_err)
					 	Next_state	=State_CRCErrEnd;
					 else
					 	Next_state	=State_OkEnd; 
			State_drop:                                 
					if (!Crs_dv)                        
						Next_state	=State_ErrEnd;	    
					else                                
						Next_state	=Current_state;     
			State_OkEnd:                                
						Next_state	=State_IFG;         
			State_ErrEnd:                               
						Next_state	=State_IFG;       
 
			State_CRCErrEnd:                               
						Next_state	=State_IFG;   
			State_FFFullDrop:
					if (!Crs_dv)                        
						Next_state	=State_IFG;	    
					else                                
						Next_state	=Current_state;				                                   
			State_FFFullErrEnd:
						Next_state	=State_FFFullDrop;									      
			State_IFG:                                  
					if (IFG_counter==RX_IFG_SET)        
						Next_state	=State_idle;        
					else                                
						Next_state	=Current_state;     
 
			default:                                    
						Next_state	=State_idle;        
		endcase                                         
 
 
always @ (posedge Reset or posedge Clk)                 
	if (Reset)                                          
		IFG_counter		<=0;   
	else if (Current_state!=State_IFG)
		IFG_counter		<=0;                                
	else 
		IFG_counter		<=IFG_counter + 1;
//******************************************************************************
//gen fifo interface signals                                                     
//******************************************************************************                     
 
assign	Fifo_data	=RxD_dl1;       
 
always @(Current_state)
	if  (Current_state==State_data)
		Fifo_data_en		=1;
	else
		Fifo_data_en		=0;
 
always @(Current_state)
	if 	(Current_state==State_ErrEnd||Current_state==State_OkEnd
		 ||Current_state==State_CRCErrEnd||Current_state==State_FFFullErrEnd)
		Fifo_data_end		=1;
	else
		Fifo_data_end		=0;
 
always @(Current_state)
	if 	(Current_state==State_ErrEnd||Current_state==State_CRCErrEnd||Current_state==State_FFFullErrEnd)
		Fifo_data_err		=1;
	else
		Fifo_data_err		=0;		
 
//******************************************************************************
//CRC_chk interface                                               
//****************************************************************************** 
 
always @(Current_state)
	if (Current_state==State_data)
		CRC_en	=1;
	else
		CRC_en	=0;
 
always @(Current_state)
	if (Current_state==State_SFD)
		CRC_init	=1;
	else
		CRC_init	=0;
 
//******************************************************************************
//gen rmon signals                                         
//****************************************************************************** 	
always @ (posedge Clk or posedge Reset)
	if (Reset)	
		Frame_length_counter		<=0;
	else if (Current_state==State_SFD)
		Frame_length_counter		<=1;
	else if (Current_state==State_data)
		Frame_length_counter		<=Frame_length_counter+ 1;
 
always @ (Frame_length_counter or RX_MIN_LENGTH)
	if (Frame_length_counter<RX_MIN_LENGTH)
		Too_short	=1;
	else
		Too_short	=0;
 
always @ (*)
	if (Frame_length_counter>RX_MAX_LENGTH)
		Too_long	=1;
	else
		Too_long	=0;
 
assign Rx_pkt_length_rmon=Frame_length_counter;
 
always @ (posedge Clk or posedge Reset)
	if (Reset)
		Rx_apply_rmon	<=0; 
	else if (Current_state==State_OkEnd||Current_state==State_ErrEnd
		||Current_state==State_CRCErrEnd||Current_state==State_FFFullErrEnd)
		Rx_apply_rmon	<=1;        
	else
		Rx_apply_rmon	<=0; 
 
always @ (posedge Clk or posedge Reset)
	if (Reset)
		Rx_pkt_err_type_rmon	<=0;
	else if (Current_state==State_CRCErrEnd)
		Rx_pkt_err_type_rmon	<=3'b001	;//
	else if (Current_state==State_FFFullErrEnd)
		Rx_pkt_err_type_rmon	<=3'b010	;// 
	else if (Current_state==State_ErrEnd)
		Rx_pkt_err_type_rmon	<=3'b011	;//
	else if(Current_state==State_OkEnd)
		Rx_pkt_err_type_rmon	<=3'b100	;
 
 
 
always @ (posedge Clk or posedge Reset)
	if (Reset)
		Rx_pkt_type_rmon		<=0;
	else if (Current_state==State_OkEnd&&pause_frame_ptr)
		Rx_pkt_type_rmon		<=3'b100	;//
	else if(Current_state==State_SFD&&Next_state==State_data)
		Rx_pkt_type_rmon		<={1'b0,MRxD[7:6]};
 
always @ (posedge Clk or posedge Reset)
	if (Reset)
		broadcast_ptr	<=0;
	else if(Current_state==State_IFG)
		broadcast_ptr	<=0;
	else if(Current_state==State_SFD&&Next_state==State_data&&MRxD[7:6]==2'b11)
		broadcast_ptr	<=1;
 
 
 
//******************************************************************************
//MAC add checker signals                                                              
//******************************************************************************
always @ (Frame_length_counter or Fifo_data_en)
	if(Frame_length_counter>=0&&Frame_length_counter<=5)
		MAC_add_en	<=Fifo_data_en;
	else
		MAC_add_en	<=0;
 
//******************************************************************************
//flow control signals                                                            
//******************************************************************************
always @ (posedge Clk or posedge Reset)
	if (Reset)
		Pause_current	<=Pause_idle;
	else
		Pause_current	<=Pause_next;
 
always @ (*)
	case (Pause_current)
		Pause_idle	: 
			if(Current_state==State_SFD)
				Pause_next	=Pause_pre_syn;
			else
				Pause_next	=Pause_current;
		Pause_pre_syn:
			case (Frame_length_counter)
				16'd0:	if (RxD_dl1==8'h01)
							Pause_next	=Pause_current;
						else
							Pause_next	=Pause_idle;
				16'd1:	if (RxD_dl1==8'h80)
							Pause_next	=Pause_current;
						else
							Pause_next	=Pause_idle;			
				16'd2:	if (RxD_dl1==8'hc2)
							Pause_next	=Pause_current;
						else
							Pause_next	=Pause_idle;
				16'd3:	if (RxD_dl1==8'h00)
							Pause_next	=Pause_current;
						else
							Pause_next	=Pause_idle;
				16'd4:	if (RxD_dl1==8'h00)
							Pause_next	=Pause_current;
						else
							Pause_next	=Pause_idle;
				16'd5:	if (RxD_dl1==8'h01)
							Pause_next	=Pause_current;
						else
							Pause_next	=Pause_idle;
				16'd12:	if (RxD_dl1==8'h88)
							Pause_next	=Pause_current;
						else
							Pause_next	=Pause_idle;
				16'd13:	if (RxD_dl1==8'h08)
							Pause_next	=Pause_current;
						else
							Pause_next	=Pause_idle;
				16'd14:	if (RxD_dl1==8'h00)
							Pause_next	=Pause_current;
						else
							Pause_next	=Pause_idle;
				16'd15:	if (RxD_dl1==8'h01)
							Pause_next	=Pause_quanta_hi;
						else
							Pause_next	=Pause_idle;
				default:	Pause_next	=Pause_current;
			endcase
		Pause_quanta_hi	:
			Pause_next	=Pause_quanta_lo;
		Pause_quanta_lo :
			Pause_next	=Pause_syn;	
		Pause_syn		:
			if (Current_state==State_IFG)
				Pause_next	=Pause_idle;
			else
				Pause_next	=Pause_current;
		default
			Pause_next	=Pause_idle;
	endcase
 
always @ (posedge Clk or posedge Reset)
	if (Reset)
		pause_quanta_h		<=0;
	else if(Pause_current==Pause_quanta_hi)
		pause_quanta_h		<=RxD_dl1;
 
always @ (posedge Clk or posedge Reset)
	if (Reset)
		pause_quanta		<=0;
	else if(Pause_current==Pause_quanta_lo)
		pause_quanta		<={pause_quanta_h,RxD_dl1};
 
always @ (posedge Clk or posedge Reset)
	if (Reset)		
		pause_quanta_val_tmp	<=0;
	else if(Current_state==State_OkEnd&&Pause_current==Pause_syn)
		pause_quanta_val_tmp	<=1;
	else
		pause_quanta_val_tmp	<=0;
 
always @ (posedge Clk or posedge Reset)
	if (Reset)		
		pause_quanta_val	<=0;
	else if(Current_state==State_OkEnd&&Pause_current==Pause_syn||pause_quanta_val_tmp)
		pause_quanta_val	<=1;
	else
		pause_quanta_val	<=0;		
 
always @ (posedge Clk or posedge Reset)
	if (Reset)	
		pause_frame_ptr		<=0;
	else if(Pause_current==Pause_syn)
		pause_frame_ptr		<=1;
	else
		pause_frame_ptr		<=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.