aboutsummaryrefslogtreecommitdiffstats
path: root/eth/rtl/verilog/MAC_tx
diff options
context:
space:
mode:
authorjcorgan <jcorgan@221aa14e-8319-0410-a670-987f0aec2ac5>2008-09-08 01:00:12 +0000
committerjcorgan <jcorgan@221aa14e-8319-0410-a670-987f0aec2ac5>2008-09-08 01:00:12 +0000
commit61f2f0214c5999ea42a368a4fc99f03d8eb28d1e (patch)
treee7e24a9adc05ff1422fe3ada9926a51634741b47 /eth/rtl/verilog/MAC_tx
downloaduhd-61f2f0214c5999ea42a368a4fc99f03d8eb28d1e.tar.gz
uhd-61f2f0214c5999ea42a368a4fc99f03d8eb28d1e.tar.bz2
uhd-61f2f0214c5999ea42a368a4fc99f03d8eb28d1e.zip
Merged r9433:9527 from features/gr-usrp2 into trunk. Adds usrp2 and gr-usrp2 top-level components. Trunk passes distcheck with mb-gcc installed, but currently not without them. The key issue is that when mb-gcc is not installed, the build system skips over the usrp2/firmware directory, and the firmware include files don't get put into the dist tarball. But we can't do the usual DIST_SUBDIRS method as the firmware is a subpackage.
git-svn-id: http://gnuradio.org/svn/gnuradio/trunk@9528 221aa14e-8319-0410-a670-987f0aec2ac5
Diffstat (limited to 'eth/rtl/verilog/MAC_tx')
-rw-r--r--eth/rtl/verilog/MAC_tx/CRC_gen.v169
-rw-r--r--eth/rtl/verilog/MAC_tx/MAC_tx_FF.v722
-rw-r--r--eth/rtl/verilog/MAC_tx/MAC_tx_addr_add.v128
-rw-r--r--eth/rtl/verilog/MAC_tx/MAC_tx_ctrl.v648
-rw-r--r--eth/rtl/verilog/MAC_tx/Random_gen.v109
5 files changed, 1776 insertions, 0 deletions
diff --git a/eth/rtl/verilog/MAC_tx/CRC_gen.v b/eth/rtl/verilog/MAC_tx/CRC_gen.v
new file mode 100644
index 000000000..4a16e7c36
--- /dev/null
+++ b/eth/rtl/verilog/MAC_tx/CRC_gen.v
@@ -0,0 +1,169 @@
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// CRC_gen.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: CRC_gen.v,v $
+// Revision 1.3 2006/01/19 14:07:54 maverickist
+// verification is complete.
+//
+// Revision 1.2 2005/12/16 06:44:17 Administrator
+// replaced tab with space.
+// passed 9.6k length frame test.
+//
+// Revision 1.1.1.1 2005/12/13 01:51:45 Administrator
+// no message
+//
+
+module CRC_gen (
+Reset ,
+Clk ,
+Init ,
+Frame_data ,
+Data_en ,
+CRC_rd ,
+CRC_end ,
+CRC_out
+
+);
+input Reset ;
+input Clk ;
+input Init ;
+input [7:0] Frame_data ;
+input Data_en ;
+input CRC_rd ;
+output [7:0] CRC_out ;
+output CRC_end ;
+
+//******************************************************************************
+//internal signals
+//******************************************************************************
+reg [7:0] CRC_out ;
+reg [31:0] CRC_reg;
+reg CRC_end;
+reg [3:0] Counter;
+//******************************************************************************
+//******************************************************************************
+//input data width is 8bit, and the first bit is bit[0]
+function[31:0] NextCRC;
+ input[7:0] D;
+ input[31:0] C;
+ reg[31:0] NewCRC;
+ begin
+ NewCRC[0]=C[24]^C[30]^D[1]^D[7];
+ NewCRC[1]=C[25]^C[31]^D[0]^D[6]^C[24]^C[30]^D[1]^D[7];
+ NewCRC[2]=C[26]^D[5]^C[25]^C[31]^D[0]^D[6]^C[24]^C[30]^D[1]^D[7];
+ NewCRC[3]=C[27]^D[4]^C[26]^D[5]^C[25]^C[31]^D[0]^D[6];
+ NewCRC[4]=C[28]^D[3]^C[27]^D[4]^C[26]^D[5]^C[24]^C[30]^D[1]^D[7];
+ NewCRC[5]=C[29]^D[2]^C[28]^D[3]^C[27]^D[4]^C[25]^C[31]^D[0]^D[6]^C[24]^C[30]^D[1]^D[7];
+ NewCRC[6]=C[30]^D[1]^C[29]^D[2]^C[28]^D[3]^C[26]^D[5]^C[25]^C[31]^D[0]^D[6];
+ NewCRC[7]=C[31]^D[0]^C[29]^D[2]^C[27]^D[4]^C[26]^D[5]^C[24]^D[7];
+ NewCRC[8]=C[0]^C[28]^D[3]^C[27]^D[4]^C[25]^D[6]^C[24]^D[7];
+ NewCRC[9]=C[1]^C[29]^D[2]^C[28]^D[3]^C[26]^D[5]^C[25]^D[6];
+ NewCRC[10]=C[2]^C[29]^D[2]^C[27]^D[4]^C[26]^D[5]^C[24]^D[7];
+ NewCRC[11]=C[3]^C[28]^D[3]^C[27]^D[4]^C[25]^D[6]^C[24]^D[7];
+ NewCRC[12]=C[4]^C[29]^D[2]^C[28]^D[3]^C[26]^D[5]^C[25]^D[6]^C[24]^C[30]^D[1]^D[7];
+ NewCRC[13]=C[5]^C[30]^D[1]^C[29]^D[2]^C[27]^D[4]^C[26]^D[5]^C[25]^C[31]^D[0]^D[6];
+ NewCRC[14]=C[6]^C[31]^D[0]^C[30]^D[1]^C[28]^D[3]^C[27]^D[4]^C[26]^D[5];
+ NewCRC[15]=C[7]^C[31]^D[0]^C[29]^D[2]^C[28]^D[3]^C[27]^D[4];
+ NewCRC[16]=C[8]^C[29]^D[2]^C[28]^D[3]^C[24]^D[7];
+ NewCRC[17]=C[9]^C[30]^D[1]^C[29]^D[2]^C[25]^D[6];
+ NewCRC[18]=C[10]^C[31]^D[0]^C[30]^D[1]^C[26]^D[5];
+ NewCRC[19]=C[11]^C[31]^D[0]^C[27]^D[4];
+ NewCRC[20]=C[12]^C[28]^D[3];
+ NewCRC[21]=C[13]^C[29]^D[2];
+ NewCRC[22]=C[14]^C[24]^D[7];
+ NewCRC[23]=C[15]^C[25]^D[6]^C[24]^C[30]^D[1]^D[7];
+ NewCRC[24]=C[16]^C[26]^D[5]^C[25]^C[31]^D[0]^D[6];
+ NewCRC[25]=C[17]^C[27]^D[4]^C[26]^D[5];
+ NewCRC[26]=C[18]^C[28]^D[3]^C[27]^D[4]^C[24]^C[30]^D[1]^D[7];
+ NewCRC[27]=C[19]^C[29]^D[2]^C[28]^D[3]^C[25]^C[31]^D[0]^D[6];
+ NewCRC[28]=C[20]^C[30]^D[1]^C[29]^D[2]^C[26]^D[5];
+ NewCRC[29]=C[21]^C[31]^D[0]^C[30]^D[1]^C[27]^D[4];
+ NewCRC[30]=C[22]^C[31]^D[0]^C[28]^D[3];
+ NewCRC[31]=C[23]^C[29]^D[2];
+ NextCRC=NewCRC;
+ end
+ endfunction
+//******************************************************************************
+
+always @ (posedge Clk) // or posedge Reset)
+// if (Reset)
+// CRC_reg <=32'hffffffff;
+// else
+ if (Init)
+ CRC_reg <=32'hffffffff;
+ else if (Data_en)
+ CRC_reg <=NextCRC(Frame_data,CRC_reg);
+ else if (CRC_rd)
+ CRC_reg <={CRC_reg[23:0],8'hff};
+
+always @ (CRC_rd or CRC_reg)
+// if (CRC_rd)
+ CRC_out <=~{
+ CRC_reg[24],
+ CRC_reg[25],
+ CRC_reg[26],
+ CRC_reg[27],
+ CRC_reg[28],
+ CRC_reg[29],
+ CRC_reg[30],
+ CRC_reg[31]
+ };
+// else
+// CRC_out <=0;
+
+//caculate CRC out length ,4 cycles
+//CRC_end aligned to last CRC checksum data
+always @(posedge Clk or posedge Reset)
+ if (Reset)
+ Counter <=0;
+ else if (!CRC_rd)
+ Counter <=0;
+ else
+ Counter <=Counter + 1;
+
+always @ (Counter)
+ if (Counter==3)
+ CRC_end=1;
+ else
+ CRC_end=0;
+
+endmodule
+
+
diff --git a/eth/rtl/verilog/MAC_tx/MAC_tx_FF.v b/eth/rtl/verilog/MAC_tx/MAC_tx_FF.v
new file mode 100644
index 000000000..e62346fb7
--- /dev/null
+++ b/eth/rtl/verilog/MAC_tx/MAC_tx_FF.v
@@ -0,0 +1,722 @@
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// MAC_tx_FF.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 ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+
+module MAC_tx_FF
+ #(parameter TX_FF_DEPTH = 9)
+ (input Reset ,
+ input Clk_MAC ,
+ input Clk_SYS ,
+ //MAC_tx_ctrl
+ output reg [7:0]Fifo_data ,
+ input Fifo_rd ,
+ input Fifo_rd_finish ,
+ input Fifo_rd_retry ,
+ output reg Fifo_eop ,
+ output reg Fifo_da ,
+ output reg Fifo_ra ,
+ output reg Fifo_data_err_empty ,
+ output Fifo_data_err_full ,
+ //user interface
+ output reg Tx_mac_wa ,
+ input Tx_mac_wr ,
+ input [31:0] Tx_mac_data ,
+ input [1:0] Tx_mac_BE ,//big endian
+ input Tx_mac_sop ,
+ input Tx_mac_eop ,
+ //host interface
+ input FullDuplex ,
+ input [4:0] Tx_Hwmark ,
+ input [4:0] Tx_Lwmark ,
+ output [31:0] debug0,
+ output [31:0] debug1
+ );
+
+//******************************************************************************
+//internal signals
+//******************************************************************************
+localparam MAC_byte3 =4'd00;
+localparam MAC_byte2 =4'd01;
+localparam MAC_byte1 =4'd02;
+localparam MAC_byte0 =4'd03;
+localparam MAC_wait_finish =4'd04;
+localparam MAC_retry =4'd08;
+localparam MAC_idle =4'd09;
+localparam MAC_FFEmpty =4'd10;
+localparam MAC_FFEmpty_drop =4'd11;
+localparam MAC_pkt_sub =4'd12;
+localparam MAC_FF_Err =4'd13;
+
+
+reg [3:0] Next_state_MAC ;
+
+
+localparam SYS_idle =4'd0;
+localparam SYS_WaitSop =4'd1;
+localparam SYS_SOP =4'd2;
+localparam SYS_MOP =4'd3;
+localparam SYS_DROP =4'd4;
+localparam SYS_EOP_ok =4'd5;
+localparam SYS_FFEmpty =4'd6;
+localparam SYS_EOP_err =4'd7;
+localparam SYS_SOP_err =4'd8;
+
+reg [3:0] Next_state_SYS;
+
+reg [TX_FF_DEPTH-1:0] Add_wr ;
+reg [TX_FF_DEPTH-1:0] Add_wr_ungray ;
+reg [TX_FF_DEPTH-1:0] Add_wr_gray ;
+reg [TX_FF_DEPTH-1:0] Add_wr_gray_dl1 ;
+reg [TX_FF_DEPTH-1:0] Add_wr_gray_dl2 ;
+
+reg [TX_FF_DEPTH-1:0] Add_rd ;
+reg [TX_FF_DEPTH-1:0] Add_rd_reg ;
+reg [TX_FF_DEPTH-1:0] Add_rd_gray ;
+reg [TX_FF_DEPTH-1:0] Add_rd_gray_dl1 ;
+reg [TX_FF_DEPTH-1:0] Add_rd_gray_dl2 ;
+reg [TX_FF_DEPTH-1:0] Add_rd_ungray ;
+wire[35:0] Din ;
+wire[35:0] Dout ;
+reg Wr_en ;
+wire[TX_FF_DEPTH-1:0] Add_wr_pluse;
+wire[TX_FF_DEPTH-1:0] Add_wr_pluse_pluse;
+reg [TX_FF_DEPTH-1:TX_FF_DEPTH-5] Add_rd_reg_dl1;
+
+reg [3:0] Current_state_MAC;
+reg [3:0] Current_state_MAC_reg;
+reg [3:0] Current_state_SYS;
+reg Full;
+reg AlmostFull;
+reg Empty;
+reg [35:0] Dout_reg;
+reg Packet_number_sub_edge;
+reg Packet_number_add;
+reg [5:0] Packet_number_inFF;
+reg [5:0] Packet_number_inFF_reg;
+reg Dout_reg_en;
+reg Add_rd_add;
+
+
+reg Tx_mac_wr_dl1 ;
+reg [31:0] Tx_mac_data_dl1 ;
+reg [1:0] Tx_mac_BE_dl1 ;
+reg FF_FullErr ;
+wire[1:0] Dout_BE ;
+wire Dout_eop ;
+wire Dout_err ;
+wire[31:0] Dout_data ;
+reg Packet_number_sub_dl1 ;
+reg Packet_number_sub_dl2 ;
+reg [4:0] Fifo_data_count ;
+reg Fifo_ra_tmp ;
+reg Pkt_sub_apply_tmp ;
+reg Pkt_sub_apply ;
+reg Add_rd_reg_rdy_tmp ;
+reg Add_rd_reg_rdy ;
+reg Add_rd_reg_rdy_dl1 ;
+reg Add_rd_reg_rdy_dl2 ;
+reg [4:0] Tx_Hwmark_pl ;
+reg [4:0] Tx_Lwmark_pl ;
+reg Add_rd_jump_tmp ;
+reg Add_rd_jump_tmp_pl1 ;
+reg Add_rd_jump ;
+reg Add_rd_jump_wr_pl1 ;
+
+//******************************************************************************
+//write data to from FF .
+//domain Clk_SYS
+//******************************************************************************
+always @ (posedge Clk_SYS or posedge Reset)
+ if (Reset)
+ Current_state_SYS <=SYS_idle;
+ else
+ Current_state_SYS <=Next_state_SYS;
+
+always @ (Current_state_SYS or Tx_mac_wr or Tx_mac_sop or Full or AlmostFull
+ or Tx_mac_eop )
+ case (Current_state_SYS)
+ SYS_idle:
+ if (Tx_mac_wr&&Tx_mac_sop&&!Full)
+ Next_state_SYS =SYS_SOP;
+ else
+ Next_state_SYS =Current_state_SYS ;
+ SYS_SOP:
+ Next_state_SYS =SYS_MOP;
+ SYS_MOP:
+ if (AlmostFull)
+ Next_state_SYS =SYS_DROP;
+ else if (Tx_mac_wr&&Tx_mac_sop)
+ Next_state_SYS =SYS_SOP_err;
+ else if (Tx_mac_wr&&Tx_mac_eop)
+ Next_state_SYS =SYS_EOP_ok;
+ else
+ Next_state_SYS =Current_state_SYS ;
+ SYS_EOP_ok:
+ if (Tx_mac_wr&&Tx_mac_sop)
+ Next_state_SYS =SYS_SOP;
+ else
+ Next_state_SYS =SYS_idle;
+ SYS_EOP_err:
+ if (Tx_mac_wr&&Tx_mac_sop)
+ Next_state_SYS =SYS_SOP;
+ else
+ Next_state_SYS =SYS_idle;
+ SYS_SOP_err:
+ Next_state_SYS =SYS_DROP;
+ SYS_DROP: //FIFO overflow
+ if (Tx_mac_wr&&Tx_mac_eop)
+ Next_state_SYS =SYS_EOP_err;
+ else
+ Next_state_SYS =Current_state_SYS ;
+ default:
+ Next_state_SYS =SYS_idle;
+ endcase
+
+//delay signals
+always @ (posedge Clk_SYS or posedge Reset)
+ if (Reset)
+ begin
+ Tx_mac_wr_dl1 <=0;
+ Tx_mac_data_dl1 <=0;
+ Tx_mac_BE_dl1 <=0;
+ end
+ else
+ begin
+ Tx_mac_wr_dl1 <=Tx_mac_wr ;
+ Tx_mac_data_dl1 <=Tx_mac_data ;
+ Tx_mac_BE_dl1 <=Tx_mac_BE ;
+ end
+
+always @(Current_state_SYS)
+ if (Current_state_SYS==SYS_EOP_err)
+ FF_FullErr =1;
+ else
+ FF_FullErr =0;
+
+reg Tx_mac_eop_gen;
+
+always @(Current_state_SYS)
+ if (Current_state_SYS==SYS_EOP_err||Current_state_SYS==SYS_EOP_ok)
+ Tx_mac_eop_gen =1;
+ else
+ Tx_mac_eop_gen =0;
+
+assign Din={Tx_mac_eop_gen,FF_FullErr,Tx_mac_BE_dl1,Tx_mac_data_dl1};
+
+always @(Current_state_SYS or Tx_mac_wr_dl1)
+ if ((Current_state_SYS==SYS_SOP||Current_state_SYS==SYS_EOP_ok||
+ Current_state_SYS==SYS_MOP||Current_state_SYS==SYS_EOP_err)&&Tx_mac_wr_dl1)
+ Wr_en = 1;
+ else
+ Wr_en = 0;
+
+
+//
+
+
+always @ (posedge Reset or posedge Clk_SYS)
+ if (Reset)
+ Add_wr_gray <=0;
+ else
+ begin : Add_wr_gray_loop
+ integer i;
+ Add_wr_gray[TX_FF_DEPTH-1] <=Add_wr[TX_FF_DEPTH-1];
+ for (i=TX_FF_DEPTH-2;i>=0;i=i-1)
+ Add_wr_gray[i] <=Add_wr[i+1]^Add_wr[i];
+ end
+
+always @ (posedge Clk_SYS or posedge Reset)
+ if (Reset)
+ Add_rd_gray_dl1 <=0;
+ else
+ Add_rd_gray_dl1 <=Add_rd_gray;
+
+ always @(posedge Clk_SYS or posedge Reset)
+ if (Reset)
+ Add_rd_gray_dl2 <= 0;
+ else
+ Add_rd_gray_dl2 <= Add_rd_gray_dl1;
+
+always @ (posedge Clk_SYS or posedge Reset)
+ if (Reset)
+ Add_rd_jump_wr_pl1 <=0;
+ else
+ Add_rd_jump_wr_pl1 <=Add_rd_jump;
+
+always @ (posedge Clk_SYS or posedge Reset)
+ if (Reset)
+ Add_rd_ungray =0;
+ else if (!Add_rd_jump_wr_pl1)
+ begin : Add_rd_ungray_loop
+ integer i;
+ Add_rd_ungray[TX_FF_DEPTH-1] = Add_rd_gray_dl2[TX_FF_DEPTH-1];
+ for (i=TX_FF_DEPTH-2;i>=0;i=i-1)
+ Add_rd_ungray[i] = Add_rd_ungray[i+1]^Add_rd_gray_dl2[i];
+ end
+
+assign Add_wr_pluse =Add_wr+1;
+assign Add_wr_pluse_pluse =Add_wr+4;
+
+always @ (Add_wr_pluse or Add_rd_ungray)
+ if (Add_wr_pluse==Add_rd_ungray)
+ Full =1;
+ else
+ Full =0;
+
+always @ (posedge Clk_SYS or posedge Reset)
+ if (Reset)
+ AlmostFull <=0;
+ else if (Add_wr_pluse_pluse==Add_rd_ungray)
+ AlmostFull <=1;
+ else
+ AlmostFull <=0;
+
+always @ (posedge Clk_SYS or posedge Reset)
+ if (Reset)
+ Add_wr <= 0;
+ else if (Wr_en&&!Full)
+ Add_wr <= Add_wr +1;
+
+always @ (posedge Clk_SYS or posedge Reset)
+ if (Reset)
+ begin
+ Packet_number_sub_dl1 <=0;
+ Packet_number_sub_dl2 <=0;
+ end
+ else
+ begin
+ Packet_number_sub_dl1 <=Pkt_sub_apply;
+ Packet_number_sub_dl2 <=Packet_number_sub_dl1;
+ end
+
+always @ (posedge Clk_SYS or posedge Reset)
+ if (Reset)
+ Packet_number_sub_edge <=0;
+ else if (Packet_number_sub_dl1&!Packet_number_sub_dl2)
+ Packet_number_sub_edge <=1;
+ else
+ Packet_number_sub_edge <=0;
+
+always @ (posedge Clk_SYS or posedge Reset)
+ if (Reset)
+ Packet_number_add <=0;
+ else if (Current_state_SYS==SYS_EOP_ok||Current_state_SYS==SYS_EOP_err)
+ Packet_number_add <=1;
+ else
+ Packet_number_add <=0;
+
+
+always @ (posedge Clk_SYS or posedge Reset)
+ if (Reset)
+ Packet_number_inFF <=0;
+ else if (Packet_number_add&&!Packet_number_sub_edge)
+ Packet_number_inFF <=Packet_number_inFF + 1'b1;
+ else if (!Packet_number_add&&Packet_number_sub_edge)
+ Packet_number_inFF <=Packet_number_inFF - 1'b1;
+
+
+always @ (posedge Clk_SYS or posedge Reset)
+ if (Reset)
+ Packet_number_inFF_reg <=0;
+ else
+ Packet_number_inFF_reg <=Packet_number_inFF;
+
+always @ (posedge Clk_SYS or posedge Reset)
+ if (Reset)
+ begin
+ Add_rd_reg_rdy_dl1 <=0;
+ Add_rd_reg_rdy_dl2 <=0;
+ end
+ else
+ begin
+ Add_rd_reg_rdy_dl1 <=Add_rd_reg_rdy;
+ Add_rd_reg_rdy_dl2 <=Add_rd_reg_rdy_dl1;
+ end
+
+always @ (posedge Clk_SYS or posedge Reset)
+ if (Reset)
+ Add_rd_reg_dl1 <=0;
+ else if (Add_rd_reg_rdy_dl1&!Add_rd_reg_rdy_dl2)
+ Add_rd_reg_dl1 <=Add_rd_reg[TX_FF_DEPTH-1:TX_FF_DEPTH-5];
+
+
+
+always @ (posedge Clk_SYS or posedge Reset)
+ if (Reset)
+ Fifo_data_count <=0;
+ else if (FullDuplex)
+ Fifo_data_count <=Add_wr[TX_FF_DEPTH-1:TX_FF_DEPTH-5]-Add_rd_ungray[TX_FF_DEPTH-1:TX_FF_DEPTH-5];
+ else
+ Fifo_data_count <=Add_wr[TX_FF_DEPTH-1:TX_FF_DEPTH-5]-Add_rd_reg_dl1[TX_FF_DEPTH-1:TX_FF_DEPTH-5]; //for half duplex backoff requirement
+
+
+always @ (posedge Clk_SYS or posedge Reset)
+ if (Reset)
+ Fifo_ra_tmp <=0;
+ else if (Packet_number_inFF_reg>=1||Fifo_data_count>=Tx_Lwmark)
+ Fifo_ra_tmp <=1;
+ else
+ Fifo_ra_tmp <=0;
+
+always @ (posedge Clk_SYS or posedge Reset)
+ if (Reset)
+ begin
+ Tx_Hwmark_pl <=0;
+ Tx_Lwmark_pl <=0;
+ end
+ else
+ begin
+ Tx_Hwmark_pl <=Tx_Hwmark;
+ Tx_Lwmark_pl <=Tx_Lwmark;
+ end
+
+always @ (posedge Clk_SYS or posedge Reset)
+ if (Reset)
+ Tx_mac_wa <=0;
+ else if (Fifo_data_count>=Tx_Hwmark_pl)
+ Tx_mac_wa <=0;
+ else if (Fifo_data_count<Tx_Lwmark_pl)
+ Tx_mac_wa <=1;
+
+//******************************************************************************
+//rd data to from FF .
+//domain Clk_MAC
+//******************************************************************************
+reg[35:0] Dout_dl1;
+
+always @ (posedge Clk_MAC or posedge Reset)
+ if (Reset)
+ Dout_dl1 <=0;
+ else
+ Dout_dl1 <=Dout;
+
+always @ (Current_state_MAC or Next_state_MAC)
+ if ((Current_state_MAC==MAC_idle||Current_state_MAC==MAC_byte0)&&Next_state_MAC==MAC_byte3)
+ Dout_reg_en =1;
+ else
+ Dout_reg_en =0;
+
+always @ (posedge Clk_MAC or posedge Reset)
+ if (Reset)
+ Dout_reg <=0;
+ else if (Dout_reg_en)
+ Dout_reg <=Dout_dl1;
+
+assign {Dout_eop,Dout_err,Dout_BE,Dout_data}=Dout_reg;
+
+always @ (posedge Clk_MAC or posedge Reset)
+ if (Reset)
+ Current_state_MAC <=MAC_idle;
+ else
+ Current_state_MAC <=Next_state_MAC;
+
+always @ (Current_state_MAC or Fifo_rd or Dout_BE or Dout_eop or Fifo_rd_retry
+ or Fifo_rd_finish or Empty or Fifo_rd or Fifo_eop)
+ case (Current_state_MAC)
+ MAC_idle:
+ if (Empty&&Fifo_rd)
+ Next_state_MAC=MAC_FF_Err;
+ else if (Fifo_rd)
+ Next_state_MAC=MAC_byte3;
+ else
+ Next_state_MAC=Current_state_MAC;
+ MAC_byte3:
+ if (Fifo_rd_retry)
+ Next_state_MAC=MAC_retry;
+ else if (Fifo_eop)
+ Next_state_MAC=MAC_wait_finish;
+ else if (Fifo_rd&&!Fifo_eop)
+ Next_state_MAC=MAC_byte2;
+ else
+ Next_state_MAC=Current_state_MAC;
+ MAC_byte2:
+ if (Fifo_rd_retry)
+ Next_state_MAC=MAC_retry;
+ else if (Fifo_eop)
+ Next_state_MAC=MAC_wait_finish;
+ else if (Fifo_rd&&!Fifo_eop)
+ Next_state_MAC=MAC_byte1;
+ else
+ Next_state_MAC=Current_state_MAC;
+ MAC_byte1:
+ if (Fifo_rd_retry)
+ Next_state_MAC=MAC_retry;
+ else if (Fifo_eop)
+ Next_state_MAC=MAC_wait_finish;
+ else if (Fifo_rd&&!Fifo_eop)
+ Next_state_MAC=MAC_byte0;
+ else
+ Next_state_MAC=Current_state_MAC;
+ MAC_byte0:
+ if (Empty&&Fifo_rd&&!Fifo_eop)
+ Next_state_MAC=MAC_FFEmpty;
+ else if (Fifo_rd_retry)
+ Next_state_MAC=MAC_retry;
+ else if (Fifo_eop)
+ Next_state_MAC=MAC_wait_finish;
+ else if (Fifo_rd&&!Fifo_eop)
+ Next_state_MAC=MAC_byte3;
+ else
+ Next_state_MAC=Current_state_MAC;
+ MAC_retry:
+ Next_state_MAC=MAC_idle;
+ MAC_wait_finish:
+ if (Fifo_rd_finish)
+ Next_state_MAC=MAC_pkt_sub;
+ else
+ Next_state_MAC=Current_state_MAC;
+ MAC_pkt_sub:
+ Next_state_MAC=MAC_idle;
+ MAC_FFEmpty:
+ if (!Empty)
+ Next_state_MAC=MAC_byte3;
+ else
+ Next_state_MAC=Current_state_MAC;
+ MAC_FF_Err: //stopped state-machine need change
+ Next_state_MAC=Current_state_MAC;
+ default
+ Next_state_MAC=MAC_idle;
+ endcase
+//
+always @ (posedge Reset or posedge Clk_MAC)
+ if (Reset)
+ Add_rd_gray <=0;
+ else
+ begin : Add_rd_gray_loop
+ integer i;
+ Add_rd_gray[TX_FF_DEPTH-1] <=Add_rd[TX_FF_DEPTH-1];
+ for (i=TX_FF_DEPTH-2;i>=0;i=i-1)
+ Add_rd_gray[i] <= Add_rd[i+1]^Add_rd[i];
+ end
+//
+
+always @ (posedge Clk_MAC or posedge Reset)
+ if (Reset)
+ Add_wr_gray_dl1 <=0;
+ else
+ Add_wr_gray_dl1 <=Add_wr_gray;
+
+always @ (posedge Clk_MAC or posedge Reset)
+ if (Reset)
+ Add_wr_gray_dl2 <=0;
+ else
+ Add_wr_gray_dl2 <=Add_wr_gray_dl1;
+
+always @ (posedge Clk_MAC or posedge Reset)
+ if (Reset)
+ Add_wr_ungray =0;
+ else
+ begin : Add_wr_ungray_loop
+ integer i;
+ Add_wr_ungray[TX_FF_DEPTH-1] = Add_wr_gray_dl2[TX_FF_DEPTH-1];
+ for (i=TX_FF_DEPTH-2;i>=0;i=i-1)
+ Add_wr_ungray[i] = Add_wr_ungray[i+1]^Add_wr_gray_dl2[i];
+ end
+
+//empty
+always @ (posedge Clk_MAC or posedge Reset)
+ if (Reset)
+ Empty <=1;
+ else if (Add_rd==Add_wr_ungray)
+ Empty <=1;
+ else
+ Empty <=0;
+
+//ra
+always @ (posedge Clk_MAC or posedge Reset)
+ if (Reset)
+ Fifo_ra <=0;
+ else
+ Fifo_ra <=Fifo_ra_tmp;
+
+
+
+always @ (posedge Clk_MAC or posedge Reset)
+ if (Reset)
+ Pkt_sub_apply_tmp <=0;
+ else if (Current_state_MAC==MAC_pkt_sub)
+ Pkt_sub_apply_tmp <=1;
+ else
+ Pkt_sub_apply_tmp <=0;
+
+always @ (posedge Clk_MAC or posedge Reset)
+ if (Reset)
+ Pkt_sub_apply <=0;
+ else if ((Current_state_MAC==MAC_pkt_sub)||Pkt_sub_apply_tmp)
+ Pkt_sub_apply <=1;
+ else
+ Pkt_sub_apply <=0;
+
+//reg Add_rd for collison retry
+always @ (posedge Clk_MAC or posedge Reset)
+ if (Reset)
+ Add_rd_reg <=0;
+ else if (Fifo_rd_finish)
+ Add_rd_reg <=Add_rd;
+
+always @ (posedge Clk_MAC or posedge Reset)
+ if (Reset)
+ Add_rd_reg_rdy_tmp <=0;
+ else if (Fifo_rd_finish)
+ Add_rd_reg_rdy_tmp <=1;
+ else
+ Add_rd_reg_rdy_tmp <=0;
+
+always @ (posedge Clk_MAC or posedge Reset)
+ if (Reset)
+ Add_rd_reg_rdy <=0;
+ else if (Fifo_rd_finish||Add_rd_reg_rdy_tmp)
+ Add_rd_reg_rdy <=1;
+ else
+ Add_rd_reg_rdy <=0;
+
+
+always @ (Current_state_MAC or Next_state_MAC)
+ if ((Current_state_MAC==MAC_idle||Current_state_MAC==MAC_byte0)&&Next_state_MAC==MAC_byte3)
+ Add_rd_add =1;
+ else
+ Add_rd_add =0;
+
+
+always @ (posedge Clk_MAC or posedge Reset)
+ if (Reset)
+ Add_rd <=0;
+ else if (Current_state_MAC==MAC_retry)
+ Add_rd <= Add_rd_reg;
+ else if (Add_rd_add)
+ Add_rd <= Add_rd + 1;
+
+always @ (posedge Clk_MAC or posedge Reset)
+ if (Reset)
+ Add_rd_jump_tmp <=0;
+ else if (Current_state_MAC==MAC_retry)
+ Add_rd_jump_tmp <=1;
+ else
+ Add_rd_jump_tmp <=0;
+
+always @ (posedge Clk_MAC or posedge Reset)
+ if (Reset)
+ Add_rd_jump_tmp_pl1 <=0;
+ else
+ Add_rd_jump_tmp_pl1 <=Add_rd_jump_tmp;
+
+always @ (posedge Clk_MAC or posedge Reset)
+ if (Reset)
+ Add_rd_jump <=0;
+ else if (Current_state_MAC==MAC_retry)
+ Add_rd_jump <=1;
+ else if (Add_rd_jump_tmp_pl1)
+ Add_rd_jump <=0;
+
+//gen Fifo_data
+
+
+always @ (Dout_data or Current_state_MAC)
+ case (Current_state_MAC)
+ MAC_byte3:
+ Fifo_data =Dout_data[31:24];
+ MAC_byte2:
+ Fifo_data =Dout_data[23:16];
+ MAC_byte1:
+ Fifo_data =Dout_data[15:8];
+ MAC_byte0:
+ Fifo_data =Dout_data[7:0];
+ default:
+ Fifo_data =0;
+ endcase
+
+always @ (posedge Clk_MAC or posedge Reset)
+ if (Reset)
+ Fifo_da <=0;
+ else if ((Current_state_MAC==MAC_byte0||Current_state_MAC==MAC_byte1||
+ Current_state_MAC==MAC_byte2||Current_state_MAC==MAC_byte3)&&Fifo_rd&&!Fifo_eop)
+ Fifo_da <=1;
+ else
+ Fifo_da <=0;
+
+//gen Fifo_data_err_empty
+assign Fifo_data_err_full=Dout_err;
+//gen Fifo_data_err_empty
+always @ (posedge Clk_MAC or posedge Reset)
+ if (Reset)
+ Current_state_MAC_reg <=0;
+ else
+ Current_state_MAC_reg <=Current_state_MAC;
+
+always @ (posedge Clk_MAC or posedge Reset)
+ if (Reset)
+ Fifo_data_err_empty <=0;
+ else if (Current_state_MAC_reg==MAC_FFEmpty)
+ Fifo_data_err_empty <=1;
+ else
+ Fifo_data_err_empty <=0;
+
+//always @ (posedge Clk_MAC)
+// if (Current_state_MAC_reg==MAC_FF_Err)
+// begin
+// $finish(2);
+// $display("mac_tx_FF meet error status at time :%t",$time);
+// end
+
+//gen Fifo_eop aligned to last valid data byte
+always @ ( Current_state_MAC or Dout_eop or Dout_BE )
+ if ( ( ( Current_state_MAC==MAC_byte0 && Dout_BE==2'b00 ) ||
+ ( Current_state_MAC==MAC_byte1 && Dout_BE==2'b11 ) ||
+ ( Current_state_MAC==MAC_byte2 && Dout_BE==2'b10 ) ||
+ ( Current_state_MAC==MAC_byte3 && Dout_BE==2'b01 ) ) && Dout_eop )
+ Fifo_eop = 1;
+ else
+ Fifo_eop = 0;
+
+ // Dual port RAM for FIFO
+ ram_2port #(.DWIDTH(36),.AWIDTH(TX_FF_DEPTH)) mac_tx_ff_ram
+ (.clka(Clk_SYS),.ena(1'b1),.wea(Wr_en),.addra(Add_wr),.dia(Din),.doa(),
+ .clkb(Clk_MAC),.enb(1'b1),.web(1'b0),.addrb(Add_rd),.dib(36'b0),.dob(Dout) );
+
+ assign debug0 =
+ { { 5'd0, Empty, Full, AlmostFull },
+ { Current_state_SYS, Current_state_MAC },
+ { Fifo_rd, Fifo_rd_finish, Fifo_rd_retry, Fifo_eop, Fifo_da, Fifo_ra, Fifo_data_err_empty, Fifo_data_err_full },
+ { 2'b0, Dout_BE, Tx_mac_wa, Tx_mac_wr, Tx_mac_sop, Tx_mac_eop} };
+
+ assign debug1 =
+ { { 8'd0 },
+ { 8'd0 },
+ { 8'd0 },
+ { 8'd0 } };
+
+endmodule // MAC_tx_FF
diff --git a/eth/rtl/verilog/MAC_tx/MAC_tx_addr_add.v b/eth/rtl/verilog/MAC_tx/MAC_tx_addr_add.v
new file mode 100644
index 000000000..76026ce06
--- /dev/null
+++ b/eth/rtl/verilog/MAC_tx/MAC_tx_addr_add.v
@@ -0,0 +1,128 @@
+// ////////////////////////////////////////////////////////////////////
+// // ////
+// // MAC_tx_addr_add.v ////
+// // ////
+// // This file is part of the Ethernet IP core project ////
+// // http://www.opencores.org/projects.cgi/wr_en/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: MAC_tx_addr_add.v,v $
+// Revision 1.3 2006/01/19 14:07:54 maverickist
+// verification is complete.
+//
+// Revision 1.2 2005/12/16 06:44:18 Administrator
+// replaced tab with space.
+// passed 9.6k length frame test.
+//
+// Revision 1.1.1.1 2005/12/13 01:51:45 Administrator
+// no message
+//
+
+module MAC_tx_addr_add
+ (Reset ,
+ Clk ,
+ MAC_tx_addr_init ,
+ MAC_tx_addr_rd ,
+ MAC_tx_addr_data ,
+ //CPU ,
+ MAC_add_prom_data ,
+ MAC_add_prom_add ,
+ MAC_add_prom_wr
+ );
+
+ input Reset ;
+ input Clk ;
+ input MAC_tx_addr_rd ;
+ input MAC_tx_addr_init ;
+ output [7:0] MAC_tx_addr_data ;
+ //CPU ;
+ input [7:0] MAC_add_prom_data ;
+ input [2:0] MAC_add_prom_add ;
+ input MAC_add_prom_wr ;
+
+ // ******************************************************************************
+ // internal signals
+ // ******************************************************************************
+ reg [2:0] add_rd;
+ wire [2:0] add_wr;
+ wire [7:0] din;
+ //wire [7:0] dout;
+ reg [7:0] dout;
+ wire wr_en;
+ reg MAC_add_prom_wr_dl1;
+ reg MAC_add_prom_wr_dl2;
+ // ******************************************************************************
+ // write data from cpu to prom
+ // ******************************************************************************
+ always @ (posedge Clk or posedge Reset)
+ if (Reset)
+ begin
+ MAC_add_prom_wr_dl1 <=0;
+ MAC_add_prom_wr_dl2 <=0;
+ end
+ else
+ begin
+ MAC_add_prom_wr_dl1 <=MAC_add_prom_wr;
+ MAC_add_prom_wr_dl2 <=MAC_add_prom_wr_dl1;
+ end
+
+ assign wr_en =MAC_add_prom_wr_dl1&!MAC_add_prom_wr_dl2;
+ assign add_wr =MAC_add_prom_add;
+ assign din =MAC_add_prom_data;
+
+ // ******************************************************************************
+ // read data from cpu to prom
+ // ******************************************************************************
+ always @ (posedge Clk or posedge Reset)
+ if (Reset)
+ add_rd <=0;
+ else if (MAC_tx_addr_init)
+ add_rd <=0;
+ else if (MAC_tx_addr_rd)
+ add_rd <=add_rd + 1;
+ assign MAC_tx_addr_data=dout;
+ // ******************************************************************************
+ // b port for read ,a port for write .
+ // ******************************************************************************
+
+ reg [7:0] address_ram [0:7];
+ always @(posedge Clk)
+ if(wr_en)
+ address_ram[add_wr] <= din;
+
+ always @(posedge Clk)
+ dout <= address_ram[add_rd];
+
+endmodule // MAC_tx_addr_add
diff --git a/eth/rtl/verilog/MAC_tx/MAC_tx_ctrl.v b/eth/rtl/verilog/MAC_tx/MAC_tx_ctrl.v
new file mode 100644
index 000000000..0fd7c603e
--- /dev/null
+++ b/eth/rtl/verilog/MAC_tx/MAC_tx_ctrl.v
@@ -0,0 +1,648 @@
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// 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: MAC_tx_Ctrl.v,v $
+// Revision 1.4 2006/06/25 04:58:56 maverickist
+// no message
+//
+// Revision 1.3 2006/01/19 14:07:54 maverickist
+// verification is complete.
+//
+// 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
+// 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_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 [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;
+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 [15:0] pause_quanta_set_dl1 ;
+reg xoff_gen_complete ;
+reg xon_gen_complete ;
+//******************************************************************************
+//boundery signal processing
+//******************************************************************************
+always @(posedge Clk or posedge Reset)
+ if (Reset)
+ begin
+ pause_quanta_set_dl1 <=0;
+ end
+ else
+ begin
+ pause_quanta_set_dl1 <=pause_quanta_set ;
+ end
+//******************************************************************************
+//state machine
+//******************************************************************************
+assign Collision=TxEn&CRS;
+
+always @(posedge Clk or posedge Reset)
+ if (Reset)
+ IPLengthCounter <=0;
+ else if (Current_state==StateDefer)
+ IPLengthCounter <=0;
+ else if (IPLengthCounter!=8'hff&&(Current_state==StateData||Current_state==StateSendPauseFrame||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))//remove some additional time
+ Next_state=StateIdle;
+ else
+ Next_state=Current_state;
+ StateIdle:
+ if (!FullDuplex&&CRS)
+ Next_state=StateDefer;
+ else if (xoff_gen||xon_gen)
+ Next_state=StatePreamble;
+ else if (pause_apply)
+ Next_state=StatePause;
+ else if ((FullDuplex||~CRS)&&Fifo_ra)
+ Next_state=StatePreamble;
+ else
+ Next_state=Current_state;
+ StatePause:
+ if (pause_counter==512/8)
+ Next_state=StateDefer;
+ else if (xoff_gen||xon_gen)
+ Next_state=StateIdle;
+ else
+ Next_state=Current_state;
+ StatePreamble:
+ if (!FullDuplex&&Collision)
+ Next_state=StateJam;
+ else if ((FullDuplex&&Preamble_counter==6)||(!FullDuplex&&!Collision&&Preamble_counter==6))
+ Next_state=StateSFD;
+ else
+ Next_state=Current_state;
+ StateSFD:
+ if (!FullDuplex&&Collision)
+ Next_state=StateJam;
+ else if (xoff_gen||xon_gen)
+ Next_state=StateSendPauseFrame;
+ else
+ Next_state=StateData;
+ StateSendPauseFrame:
+ if (IPLengthCounter==17)
+ 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 (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==StateSendPauseFrame||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&&!(xoff_gen||xon_gen) ||
+ 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==StateSendPauseFrame||
+ 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&&MAC_tx_add_en)
+ TxD_tmp =MAC_tx_addr_data;
+ else
+ case (IPLengthCounter)
+ 8'd0: TxD_tmp =8'h01;
+ 8'd1: TxD_tmp =8'h80;
+ 8'd2: TxD_tmp =8'hc2;
+ 8'd3: TxD_tmp =8'h00;
+ 8'd4: TxD_tmp =8'h00;
+ 8'd5: TxD_tmp =8'h01;
+ 8'd12: TxD_tmp =8'h88;//type
+ 8'd13: TxD_tmp =8'h08;//
+ 8'd14: TxD_tmp =8'h00;//opcode
+ 8'd15: TxD_tmp =8'h01;
+ 8'd16: TxD_tmp =xon_gen?8'b0:pause_quanta_set_dl1[15:8];
+ 8'd17: TxD_tmp =xon_gen?8'b0:pause_quanta_set_dl1[7:0];
+// 8'd60: TxD_tmp =8'h26;
+// 8'd61: TxD_tmp =8'h6b;
+// 8'd62: TxD_tmp =8'hae;
+// 8'd63: TxD_tmp =8'h0a;
+ 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||Current_state==StateSendPauseFrame||Current_state==StatePAD||Current_state==StateFCS)
+ Tx_pkt_length_rmon <=Tx_pkt_length_rmon+1;
+
+
+reg [2:0] Tx_apply_rmon_reg;
+
+always @( posedge Clk or posedge Reset )
+ if ( Reset )
+ begin
+ Tx_apply_rmon <= 0;
+ Tx_apply_rmon_reg <= 'b0;
+ end
+ else
+ begin
+ if ( (Fifo_eop&&Current_state==StateJamDrop) ||
+ (Fifo_eop&&Current_state==StateFFEmptyDrop) ||
+ CRC_end )
+ Tx_apply_rmon <= 1;
+ else
+ if ( Tx_apply_rmon_reg[2] )
+ Tx_apply_rmon <= 0;
+
+ Tx_apply_rmon_reg <= { Tx_apply_rmon_reg[1:0], Tx_apply_rmon };
+ end
+
+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;//normal
+
+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 <=1;
+ 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[7:6]};
+
+
+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 @ (posedge Clk or posedge Reset)
+ if (Reset)
+ 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
+ MAC_tx_addr_rd <=0;
+
+ always @*
+ //if ((Tx_pkt_length_rmon==3)&&Fifo_rd)
+ if (Current_state==StatePreamble)
+ MAC_tx_addr_init=1;
+ else
+ MAC_tx_addr_init=0;
+
+//**************************************************************************************************************
+// CFH: this implementation delays the time it sends an entire Ethernet frame with 512 bits for every pause
+// request of 512 bits. Actually, it should only delay the time it takes to transmit 512 bits, not counting
+// Ethernet header, CRC, Interframe Gap etc.
+// Hence the current implementation waits longer than the pause frame actually requests (~20% more)
+//**************************************************************************************************************
+
+//flow control
+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)
+ pause_quanta_sub <=0;
+ else if(pause_counter==512/8)
+ pause_quanta_sub <=1;
+ else
+ pause_quanta_sub <=0;
+
+// FIXME The below probably won't work if the pause request comes when we are in the wrong state
+ wire clear_xonxoff = (Current_state==StateSendPauseFrame) & (IPLengthCounter==17);
+always @ (posedge Clk or posedge Reset)
+ if (Reset)
+ xoff_gen_complete <=0;
+ else if(clear_xonxoff & xoff_gen)
+ xoff_gen_complete <=1;
+ else
+ xoff_gen_complete <=0;
+
+
+always @ (posedge Clk or posedge Reset)
+ if (Reset)
+ xon_gen_complete <=0;
+ else if(clear_xonxoff & xon_gen)
+ xon_gen_complete <=1;
+ else
+ xon_gen_complete <=0;
+
+endmodule
diff --git a/eth/rtl/verilog/MAC_tx/Random_gen.v b/eth/rtl/verilog/MAC_tx/Random_gen.v
new file mode 100644
index 000000000..fd57008b1
--- /dev/null
+++ b/eth/rtl/verilog/MAC_tx/Random_gen.v
@@ -0,0 +1,109 @@
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Random_gen.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 ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+
+module Random_gen(
+Reset ,
+Clk ,
+Init ,
+RetryCnt ,
+Random_time_meet
+);
+input Reset ;
+input Clk ;
+input Init ;
+input [3:0] RetryCnt ;
+output Random_time_meet;
+
+//******************************************************************************
+//internal signals
+//******************************************************************************
+reg [9:0] Random_sequence ;
+reg [9:0] Random ;
+reg [9:0] Random_counter ;
+reg [7:0] Slot_time_counter; //256*2=512bit=1 slot time
+reg Random_time_meet;
+
+//******************************************************************************
+always @ (posedge Clk or posedge Reset)
+ if (Reset)
+ Random_sequence <=0;
+ else
+ Random_sequence <={Random_sequence[8:0],~(Random_sequence[2]^Random_sequence[9])};
+
+always @ (RetryCnt or Random_sequence)
+ case (RetryCnt)
+ 4'h0 : Random={9'b0,Random_sequence[0]};
+ 4'h1 : Random={8'b0,Random_sequence[1:0]};
+ 4'h2 : Random={7'b0,Random_sequence[2:0]};
+ 4'h3 : Random={6'b0,Random_sequence[3:0]};
+ 4'h4 : Random={5'b0,Random_sequence[4:0]};
+ 4'h5 : Random={4'b0,Random_sequence[5:0]};
+ 4'h6 : Random={3'b0,Random_sequence[6:0]};
+ 4'h7 : Random={2'b0,Random_sequence[7:0]};
+ 4'h8 : Random={1'b0,Random_sequence[8:0]};
+ 4'h9 : Random={ Random_sequence[9:0]};
+ default : Random={ Random_sequence[9:0]};
+ endcase
+
+always @ (posedge Clk or posedge Reset)
+ if (Reset)
+ Slot_time_counter <=0;
+ else if(Init)
+ Slot_time_counter <=0;
+ else if(!Random_time_meet)
+ Slot_time_counter <=Slot_time_counter+1;
+
+always @ (posedge Clk or posedge Reset)
+ if (Reset)
+ Random_counter <=0;
+ else if (Init)
+ Random_counter <=Random;
+ else if (Random_counter!=0&&Slot_time_counter==255)
+ Random_counter <=Random_counter -1 ;
+
+always @ (posedge Clk or posedge Reset)
+ if (Reset)
+ Random_time_meet <=1;
+ else if (Init)
+ Random_time_meet <=0;
+ else if (Random_counter==0)
+ Random_time_meet <=1;
+
+endmodule
+
+