From 61f2f0214c5999ea42a368a4fc99f03d8eb28d1e Mon Sep 17 00:00:00 2001 From: jcorgan Date: Mon, 8 Sep 2008 01:00:12 +0000 Subject: 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 --- eth/rtl/verilog/MAC_tx/CRC_gen.v | 169 ++++++++ eth/rtl/verilog/MAC_tx/MAC_tx_FF.v | 722 +++++++++++++++++++++++++++++++ eth/rtl/verilog/MAC_tx/MAC_tx_addr_add.v | 128 ++++++ eth/rtl/verilog/MAC_tx/MAC_tx_ctrl.v | 648 +++++++++++++++++++++++++++ eth/rtl/verilog/MAC_tx/Random_gen.v | 109 +++++ 5 files changed, 1776 insertions(+) create mode 100644 eth/rtl/verilog/MAC_tx/CRC_gen.v create mode 100644 eth/rtl/verilog/MAC_tx/MAC_tx_FF.v create mode 100644 eth/rtl/verilog/MAC_tx/MAC_tx_addr_add.v create mode 100644 eth/rtl/verilog/MAC_tx/MAC_tx_ctrl.v create mode 100644 eth/rtl/verilog/MAC_tx/Random_gen.v (limited to 'eth/rtl/verilog/MAC_tx') 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=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 + + -- cgit v1.2.3