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