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_rx/Broadcast_filter.v | 107 +++++ eth/rtl/verilog/MAC_rx/CRC_chk.v | 128 ++++++ eth/rtl/verilog/MAC_rx/MAC_rx_FF.v | 167 ++++++++ eth/rtl/verilog/MAC_rx/MAC_rx_add_chk.v | 158 +++++++ eth/rtl/verilog/MAC_rx/MAC_rx_ctrl.v | 664 ++++++++++++++++++++++++++++++ 5 files changed, 1224 insertions(+) create mode 100644 eth/rtl/verilog/MAC_rx/Broadcast_filter.v create mode 100644 eth/rtl/verilog/MAC_rx/CRC_chk.v create mode 100644 eth/rtl/verilog/MAC_rx/MAC_rx_FF.v create mode 100644 eth/rtl/verilog/MAC_rx/MAC_rx_add_chk.v create mode 100644 eth/rtl/verilog/MAC_rx/MAC_rx_ctrl.v (limited to 'eth/rtl/verilog/MAC_rx') diff --git a/eth/rtl/verilog/MAC_rx/Broadcast_filter.v b/eth/rtl/verilog/MAC_rx/Broadcast_filter.v new file mode 100644 index 000000000..bc95e31d7 --- /dev/null +++ b/eth/rtl/verilog/MAC_rx/Broadcast_filter.v @@ -0,0 +1,107 @@ +////////////////////////////////////////////////////////////////////// +//// //// +//// Broadcast_filter.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: Broadcast_filter.v,v $ +// Revision 1.3 2006/01/19 14:07:54 maverickist +// verification is complete. +// +// Revision 1.2 2005/12/16 06:44:16 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 Broadcast_filter ( +Reset , +Clk , +//MAC_rx_ctrl , +broadcast_ptr , +broadcast_drop , +//FromCPU , +broadcast_filter_en , +broadcast_bucket_depth , +broadcast_bucket_interval +); +input Reset ; +input Clk ; + //MAC_rx_ctrl +input broadcast_ptr ; +output broadcast_drop ; + //FromCPU ; +input broadcast_filter_en ; +input [15:0] broadcast_bucket_depth ; +input [15:0] broadcast_bucket_interval ; + +//****************************************************************************** +//internal signals +//****************************************************************************** +reg [15:0] time_counter ; +reg [15:0] broadcast_counter ; +reg broadcast_drop ; +//****************************************************************************** +// +//****************************************************************************** +always @ (posedge Clk or posedge Reset) + if (Reset) + time_counter <=0; + else if (time_counter==broadcast_bucket_interval) + time_counter <=0; + else + time_counter <=time_counter+1; + +always @ (posedge Clk or posedge Reset) + if (Reset) + broadcast_counter <=0; + else if (time_counter==broadcast_bucket_interval) + broadcast_counter <=0; + else if (broadcast_ptr&&broadcast_counter!=broadcast_bucket_depth) + broadcast_counter <=broadcast_counter+1; + +always @ (posedge Clk or posedge Reset) + if (Reset) + broadcast_drop <=0; + else if(broadcast_filter_en&&broadcast_counter==broadcast_bucket_depth) + broadcast_drop <=1; + else + broadcast_drop <=0; + +endmodule \ No newline at end of file diff --git a/eth/rtl/verilog/MAC_rx/CRC_chk.v b/eth/rtl/verilog/MAC_rx/CRC_chk.v new file mode 100644 index 000000000..d6bb22b51 --- /dev/null +++ b/eth/rtl/verilog/MAC_rx/CRC_chk.v @@ -0,0 +1,128 @@ +////////////////////////////////////////////////////////////////////// +//// //// +//// CRC_chk.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_chk.v,v $ +// Revision 1.3 2006/01/19 14:07:54 maverickist +// verification is complete. +// +// Revision 1.2 2005/12/16 06:44:16 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_chk( +Reset , +Clk , +CRC_data , +CRC_init , +CRC_en , +//From CPU +CRC_chk_en , +CRC_err +); +input Reset ; +input Clk ; +input[7:0] CRC_data ; +input CRC_init ; +input CRC_en ; + //From CPU +input CRC_chk_en ; +output CRC_err ; +//****************************************************************************** +//internal signals +//****************************************************************************** +reg [31:0] CRC_reg; +//****************************************************************************** +//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 (CRC_init) + CRC_reg <=32'hffffffff; + else if (CRC_en) + CRC_reg <=NextCRC(CRC_data,CRC_reg); + +assign CRC_err = CRC_chk_en&(CRC_reg[31:0] != 32'hc704dd7b); + +endmodule diff --git a/eth/rtl/verilog/MAC_rx/MAC_rx_FF.v b/eth/rtl/verilog/MAC_rx/MAC_rx_FF.v new file mode 100644 index 000000000..e212b8986 --- /dev/null +++ b/eth/rtl/verilog/MAC_rx/MAC_rx_FF.v @@ -0,0 +1,167 @@ + +// //////////////////////////////////////////////////////////////////// +// Completely Rewritten by M. Ettus, no John Gao code left +// //////////////////////////////////////////////////////////////////// + +module MAC_rx_FF + #(parameter RX_FF_DEPTH = 9) + (input Reset, + input Clk_MAC, + input Clk_SYS, + + // MAC_rx_ctrl interface + input [7:0] Fifo_data, + input Fifo_data_en, + output Fifo_full, + input Fifo_data_err, + input Fifo_data_end, + output [15:0] Fifo_space, + + // CPU + input RX_APPEND_CRC, + input [4:0] Rx_Hwmark, + input [4:0] Rx_Lwmark, + + // User interface + output Rx_mac_empty, + input Rx_mac_rd, + output [31:0] Rx_mac_data, + output [1:0] Rx_mac_BE, + output Rx_mac_sop, + output Rx_mac_eop, + output Rx_mac_err, + + // FIFO Levels + output [15:0] fifo_occupied, + output fifo_full_dbg, + output fifo_empty + ); + + reg [1:0] FF_state; + reg [2:0] PKT_state; + reg [31:0] staging; + reg [35:0] staging2; + reg line_ready, line_ready_d1; + wire sop_i, eop_i; + reg [1:0] be; + + always @(posedge Clk_MAC or posedge Reset) + if(Reset) + FF_state <= 0; + else + if(Fifo_data_err | Fifo_data_end) + FF_state <= 0; + else if(Fifo_data_en) + FF_state <= FF_state + 1; + + always @(posedge Clk_MAC or posedge Reset) + if(Reset) + staging[31:0] <= 0; + else if(Fifo_data_en) + case(FF_state) + 0 : staging[31:24] <= Fifo_data; + 1 : staging[23:16] <= Fifo_data; + 2 : staging[15:8] <= Fifo_data; + 3 : staging[7:0] <= Fifo_data; + endcase // case(FF_state) + + localparam PKT_idle = 0; + localparam PKT_sop = 1; + localparam PKT_pkt = 2; + localparam PKT_end = 3; + localparam PKT_err = 4; + + always @(posedge Clk_MAC or posedge Reset) + if(Reset) + PKT_state <= 0; + else + case(PKT_state) + PKT_idle : + if(Fifo_data_en) + PKT_state <= PKT_sop; + PKT_sop, PKT_pkt : + if(Fifo_data_err | (line_ready & Fifo_full)) + PKT_state <= PKT_err; + else if(Fifo_data_end) + PKT_state <= PKT_end; + else if(line_ready & ~Fifo_full) + PKT_state <= PKT_pkt; + PKT_end : + PKT_state <= PKT_idle; + PKT_err : + if(~Fifo_full) + PKT_state <= PKT_idle; + endcase // case(PKT_state) + + assign sop_i = (PKT_state == PKT_sop); + assign eop_i = (PKT_state == PKT_end); + + always @(posedge Clk_MAC) + if(line_ready) + staging2 <= {sop_i, eop_i, be[1:0], staging}; + + always @(posedge Clk_MAC) + if(Reset) + line_ready <= 0; + else if((Fifo_data_en & (FF_state==2'd3)) | Fifo_data_end | Fifo_data_err) + line_ready <= 1; + else + line_ready <= 0; + + always @(posedge Clk_MAC) + line_ready_d1 <= line_ready; + + always @(posedge Clk_MAC) + if(Fifo_data_end | Fifo_data_err) + be <= FF_state; + else + be <= 0; + + wire sop_o, eop_o, empty; + wire [1:0] be_o; + wire [RX_FF_DEPTH-1:0] occupied, occupied_sysclk; + wire [31:0] dataout; + +/* + fifo_2clock #(.DWIDTH(36),.AWIDTH(RX_FF_DEPTH)) mac_rx_fifo + (.wclk(Clk_MAC),.datain((PKT_state==PKT_err) ? 36'hF_FFFF_FFFF : staging2),.write(~Fifo_full & (line_ready_d1|(PKT_state==PKT_err))), + .full(Fifo_full),.level_wclk(occupied), + .rclk(Clk_SYS),.dataout({sop_o,eop_o,be_o[1:0],dataout}),.read(Rx_mac_rd), + .empty(empty),.level_rclk(), + .arst(Reset) ); + */ + + fifo_xlnx_2Kx36_2clk mac_rx_ff_core + ( + .din((PKT_state==PKT_err) ? 36'hF_FFFF_FFFF : staging2), // Bus [35 : 0] + .rd_clk(Clk_SYS), + .rd_en(Rx_mac_rd), + .rst(Reset), + .wr_clk(Clk_MAC), + .wr_en(~Fifo_full & (line_ready_d1|(PKT_state==PKT_err))), + .dout({sop_o,eop_o,be_o[1:0],dataout}), // Bus [35 : 0] + .empty(empty), + .full(Fifo_full), + .rd_data_count(occupied_sysclk), // Bus [11 : 0] + .wr_data_count(occupied)); // Bus [11 : 0] + + assign Fifo_space[15:RX_FF_DEPTH] = 0; + assign Fifo_space[RX_FF_DEPTH-1:0] = ~occupied; + assign fifo_occupied = occupied_sysclk; + assign fifo_full_dbg = Fifo_full; // FIXME -- in wrong clock domain + assign fifo_empty = empty; + + // mac side fifo interface + // Input - Rx_mac_rd + // Output - Rx_mac_empty, Rx_mac_sop, Rx_mac_eop, Rx_mac_err, Rx_mac_data, Rx_mac_BE + + assign Rx_mac_BE = be_o; + assign Rx_mac_sop = sop_o & ~eop_o; + assign Rx_mac_eop = eop_o; + assign Rx_mac_err = sop_o & eop_o; + assign Rx_mac_empty = empty; + assign Rx_mac_data = dataout; + +endmodule // MAC_rx_FF + +// FIXME Should we send out an "almost full" signal instead of full? diff --git a/eth/rtl/verilog/MAC_rx/MAC_rx_add_chk.v b/eth/rtl/verilog/MAC_rx/MAC_rx_add_chk.v new file mode 100644 index 000000000..0c8d6bd4e --- /dev/null +++ b/eth/rtl/verilog/MAC_rx/MAC_rx_add_chk.v @@ -0,0 +1,158 @@ +// //////////////////////////////////////////////////////////////////// +// // //// +// // MAC_rx_add_chk.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_rx_add_chk.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 MAC_rx_add_chk + (Reset , + Clk , + Init , + data , + MAC_add_en , + MAC_rx_add_chk_err , + //From CPU + MAC_rx_add_chk_en , + MAC_add_prom_data , + MAC_add_prom_add , + MAC_add_prom_wr + ); + + input Reset ; + input Clk ; + input Init ; + input [7:0] data ; + input MAC_add_en ; + output MAC_rx_add_chk_err ; + //From CPU + input MAC_rx_add_chk_en ; + input [7:0] MAC_add_prom_data ; + input [2:0] MAC_add_prom_add ; + input MAC_add_prom_wr ; + + // ****************************************************************************** + // internal signals + // ****************************************************************************** + reg [2:0] addr_rd; + wire [2:0] addr_wr; + wire [7:0] din; + //wire [7:0] dout; + reg [7:0] dout; + wire wr_en; + + reg MAC_rx_add_chk_err; + reg MAC_add_prom_wr_dl1; + reg MAC_add_prom_wr_dl2; + reg [7:0] data_dl1 ; + reg MAC_add_en_dl1 ; + + // ****************************************************************************** + // write data from cpu to prom + // ****************************************************************************** + always @ (posedge Clk or posedge Reset) + if (Reset) + begin + data_dl1 <=0; + MAC_add_en_dl1 <=0; + end + else + begin + data_dl1 <=data; + MAC_add_en_dl1 <=MAC_add_en; + end + + 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 addr_wr =MAC_add_prom_add; + assign din =MAC_add_prom_data; + + // ****************************************************************************** + // mac add verify + // ****************************************************************************** + always @ (posedge Clk or posedge Reset) + if (Reset) + addr_rd <=0; + else if (Init) + addr_rd <=0; + else if (MAC_add_en) + addr_rd <=addr_rd + 1; + + always @ (posedge Clk or posedge Reset) + if (Reset) + MAC_rx_add_chk_err <=0; + else if (Init) + MAC_rx_add_chk_err <=0; + else if (MAC_rx_add_chk_en && MAC_add_en_dl1 && (dout!=data_dl1) ) + MAC_rx_add_chk_err <=1; + + + // ****************************************************************************** + // a port for read ,b port for write . + // ****************************************************************************** + + reg [7:0] address_ram [0:7]; + always @(posedge Clk) + if(wr_en) + address_ram[addr_wr] <= din; + + always @(posedge Clk) + dout <= address_ram[addr_rd]; + +endmodule // MAC_rx_add_chk diff --git a/eth/rtl/verilog/MAC_rx/MAC_rx_ctrl.v b/eth/rtl/verilog/MAC_rx/MAC_rx_ctrl.v new file mode 100644 index 000000000..5ab795801 --- /dev/null +++ b/eth/rtl/verilog/MAC_rx/MAC_rx_ctrl.v @@ -0,0 +1,664 @@ +////////////////////////////////////////////////////////////////////// +//// //// +//// MAC_rx_ctrl.v //// +//// //// +//// This file is part of the Ethernet IP core project //// +//// http://www.opencores.org/projects.cgi/web/ethernet_tri_mode///// +//// //// +//// Author(s): //// +//// - Jon Gao (gaojon@yahoo.com) //// +//// //// +//// //// +////////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2001 Authors //// +//// //// +//// This source file may be used and distributed without //// +//// restriction provided that this copyright statement is not //// +//// removed from the file and that any derivative work contains //// +//// the original copyright notice and the associated disclaimer. //// +//// //// +//// This source file is free software; you can redistribute it //// +//// and/or modify it under the terms of the GNU Lesser General //// +//// Public License as published by the Free Software Foundation; //// +//// either version 2.1 of the License, or (at your option) any //// +//// later version. //// +//// //// +//// This source is distributed in the hope that it will be //// +//// useful, but WITHOUT ANY WARRANTY; without even the implied //// +//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// +//// PURPOSE. See the GNU Lesser General Public License for more //// +//// details. //// +//// //// +//// You should have received a copy of the GNU Lesser General //// +//// Public License along with this source; if not, download it //// +//// from http://www.opencores.org/lgpl.shtml //// +//// //// +////////////////////////////////////////////////////////////////////// +// +// CVS Revision History +// +// $Log: MAC_rx_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:37 Administrator +// no message +// +// Revision 1.1.1.1 2005/12/13 01:51:45 Administrator +// no message +// + +module MAC_rx_ctrl ( +Reset , +Clk , +//RMII interface +MCrs_dv , // +MRxD , // +MRxErr , // +//CRC_chk interface +CRC_en , +CRC_data, +CRC_init , +CRC_err , +//MAC_rx_add_chk interface +MAC_add_en , +MAC_add_data, +MAC_rx_add_chk_err , +//broadcast_filter +broadcast_ptr , +broadcast_drop , +//flow_control signals +pause_quanta , +pause_quanta_val , +//MAC_rx_FF interface +Fifo_data , +Fifo_data_en , +Fifo_data_err , +Fifo_data_drop , +Fifo_data_end , +Fifo_full , +//RMON interface +Rx_pkt_type_rmon , +Rx_pkt_length_rmon , +Rx_apply_rmon , +Rx_pkt_err_type_rmon , +//CPU +RX_IFG_SET , +RX_MAX_LENGTH, +RX_MIN_LENGTH +); + +input Reset ; +input Clk ; + //RMII interface +input MCrs_dv ; +input [7:0] MRxD ; +input MRxErr ; + //CRC_chk interface +output CRC_en ; +output CRC_init; +output [7:0] CRC_data; +input CRC_err ; + //MAC_rx_add_chk interface +output MAC_add_en ; +output [7:0] MAC_add_data; +input MAC_rx_add_chk_err ; + //broadcast_filter +output broadcast_ptr ; +input broadcast_drop ; + //flow_control signals +output [15:0] pause_quanta ; +output pause_quanta_val ; + //MAC_rx_FF interface +output [7:0] Fifo_data ; +output Fifo_data_en ; +output Fifo_data_err ; +output Fifo_data_drop ; +output Fifo_data_end ; +input Fifo_full; + //RMON interface +output [15:0] Rx_pkt_length_rmon ; +output Rx_apply_rmon ; +output [2:0] Rx_pkt_err_type_rmon ; +output [2:0] Rx_pkt_type_rmon ; + //CPU +input [5:0] RX_IFG_SET ; +input [15:0] RX_MAX_LENGTH ;// 1518 +input [6:0] RX_MIN_LENGTH ;// 64 + +//****************************************************************************** +//internal signals +//****************************************************************************** +parameter State_idle =4'd00; +parameter State_preamble =4'd01; +parameter State_SFD =4'd02; +parameter State_data =4'd03; +parameter State_checkCRC =4'd04; +parameter State_OkEnd =4'd07; +parameter State_DropEnd =4'd08; +parameter State_ErrEnd =4'd09; +parameter State_CRCErrEnd =4'd10; +parameter State_FFFullDrop =4'd11; +parameter State_FFFullErrEnd =4'd12; +parameter State_IFG =4'd13; +parameter State_Drop2End =4'd14; + +parameter Pause_idle =4'd0; +parameter Pause_pre_syn =4'd1; +parameter Pause_quanta_hi =4'd2; +parameter Pause_quanta_lo =4'd3; +parameter Pause_syn =4'd4; + +reg [3:0] Current_state /* synthesis syn_keep=1 */; +reg [3:0] Next_state; +reg [3:0] Pause_current /* synthesis syn_keep=1 */; +reg [3:0] Pause_next; +reg [5:0] IFG_counter; +reg Crs_dv ; +reg [7:0] RxD ; +reg [7:0] RxD_dl1 ; +reg RxErr ; +reg [15:0] Frame_length_counter; +reg Too_long; +reg Too_short; +reg ProcessingHeader; +//reg Fifo_data_en; +//reg Fifo_data_err; +//reg Fifo_data_drop; +//reg Fifo_data_end; +reg CRC_en; +reg CRC_init; +reg Rx_apply_rmon; +reg [2:0] Rx_pkt_err_type_rmon; +reg MAC_add_en; +reg [2:0] Rx_pkt_type_rmon; +reg [7:0] pause_quanta_h ; +reg [15:0] pause_quanta ; +reg pause_quanta_val ; +reg pause_quanta_val_tmp; +reg pause_frame_ptr ; +reg broadcast_ptr ; +//****************************************************************************** +//delay signals +//****************************************************************************** + +always @ (posedge Reset or posedge Clk) + if (Reset) + begin + Crs_dv <=0; + RxD <=0; + RxErr <=0; + end + else + begin + Crs_dv <=MCrs_dv ; + RxD <=MRxD ; + RxErr <=MRxErr ; + end + +always @ (posedge Reset or posedge Clk) + if (Reset) + RxD_dl1 <=0; + else + RxD_dl1 <=RxD; + +//--------------------------------------------------------------------------- +// Small pre-FIFO (acutally a synchronously clearable shift-register) for +// storing the first part of a packet before writing it to the "real" FIFO +// in MAC_rx_FF. This allows a packet to be dropped safely if an error +// happens in the beginning of a packet (or if the MAC address doesn't pass +// the receive filter!) +//--------------------------------------------------------------------------- + + reg pre_fifo_data_drop; + reg pre_fifo_data_en; + reg pre_fifo_data_err; + reg pre_fifo_data_end; + wire [7:0] pre_fifo_wrdata; + + reg [8+3-1:0] pre_fifo_element_0; + reg [8+3-1:0] pre_fifo_element_1; + reg [8+3-1:0] pre_fifo_element_2; + reg [8+3-1:0] pre_fifo_element_3; + reg [8+3-1:0] pre_fifo_element_4; + reg [8+3-1:0] pre_fifo_element_5; + reg [8+3-1:0] pre_fifo_element_6; + reg [8+3-1:0] pre_fifo_element_7; + reg [8+3-1:0] pre_fifo_element_8; + reg [8+3-1:0] pre_fifo_element_9; + + always @( posedge Reset or posedge Clk ) + if ( Reset ) + begin + pre_fifo_element_0 <= 'b0; + pre_fifo_element_1 <= 'b0; + pre_fifo_element_2 <= 'b0; + pre_fifo_element_3 <= 'b0; + pre_fifo_element_4 <= 'b0; + pre_fifo_element_5 <= 'b0; + pre_fifo_element_6 <= 'b0; + pre_fifo_element_7 <= 'b0; + pre_fifo_element_8 <= 'b0; + pre_fifo_element_9 <= 'b0; + end + else + begin + if ( pre_fifo_data_drop ) + begin + pre_fifo_element_0 <= 'b0; + pre_fifo_element_1 <= 'b0; + pre_fifo_element_2 <= 'b0; + pre_fifo_element_3 <= 'b0; + pre_fifo_element_4 <= 'b0; + pre_fifo_element_5 <= 'b0; + pre_fifo_element_6 <= 'b0; + pre_fifo_element_7 <= 'b0; + pre_fifo_element_8 <= 'b0; + pre_fifo_element_9 <= 'b0; + end + else + begin + pre_fifo_element_0 <= pre_fifo_element_1; + pre_fifo_element_1 <= pre_fifo_element_2; + pre_fifo_element_2 <= pre_fifo_element_3; + pre_fifo_element_3 <= pre_fifo_element_4; + pre_fifo_element_4 <= pre_fifo_element_5; + pre_fifo_element_5 <= pre_fifo_element_6; + pre_fifo_element_6 <= pre_fifo_element_7; + pre_fifo_element_7 <= pre_fifo_element_8; + pre_fifo_element_8 <= pre_fifo_element_9; + pre_fifo_element_9 <= { pre_fifo_data_en, + pre_fifo_data_err, + pre_fifo_data_end, + pre_fifo_wrdata }; + end + end + + assign Fifo_data = pre_fifo_element_0[7:0]; + assign Fifo_data_end = pre_fifo_element_0[8]; + assign Fifo_data_err = pre_fifo_element_0[9]; + assign Fifo_data_en = pre_fifo_element_0[10]; + + assign CRC_data = pre_fifo_wrdata; + assign MAC_add_data = pre_fifo_wrdata; + +//****************************************************************************** +//State_machine +//****************************************************************************** + +always @( posedge Reset or posedge Clk ) + if ( Reset ) + Current_state <= State_idle; + else + Current_state <= Next_state; + +always @ (*) + case (Current_state) + State_idle: + if ( Crs_dv&&RxD==8'h55 ) + Next_state = State_preamble; + else + Next_state = Current_state; + + State_preamble: + if ( !Crs_dv ) + Next_state = State_DropEnd; + else if ( RxErr ) + Next_state = State_DropEnd; + else if ( RxD==8'hd5 ) + Next_state = State_SFD; + else if ( RxD==8'h55 ) + Next_state =Current_state; + else + Next_state = State_DropEnd; + + State_SFD: + if ( !Crs_dv ) + Next_state = State_DropEnd; + else if ( RxErr ) + Next_state = State_DropEnd; + else + Next_state = State_data; + + State_data: + if ( !Crs_dv && !ProcessingHeader && !Too_short && !Too_long ) + Next_state = State_checkCRC; + else if ( !Crs_dv && ProcessingHeader ) + Next_state = State_Drop2End; + else if ( !Crs_dv && (Too_short | Too_long) ) + Next_state = State_ErrEnd; + else if ( Fifo_full ) + Next_state = State_FFFullErrEnd; + else if ( RxErr && ProcessingHeader ) + Next_state = State_Drop2End; + else if ( RxErr || Too_long ) + Next_state = State_ErrEnd; + else if ( MAC_rx_add_chk_err || broadcast_drop ) + Next_state = State_DropEnd; + else + Next_state = State_data; + + State_checkCRC: + if ( CRC_err ) + Next_state = State_CRCErrEnd; + else + Next_state = State_OkEnd; + + State_OkEnd: + Next_state = State_IFG; + + State_ErrEnd: + Next_state = State_IFG; + + State_DropEnd: + Next_state = State_IFG; + + State_Drop2End: + Next_state = State_IFG; + + State_CRCErrEnd: + Next_state = State_IFG; + + State_FFFullErrEnd: + Next_state = State_FFFullDrop; + + State_FFFullDrop: + if ( !Crs_dv ) + Next_state =State_IFG; + else + Next_state =Current_state; + + State_IFG: + if ( IFG_counter==RX_IFG_SET-4 ) // Remove some additional time? + Next_state = State_idle; + else + Next_state = Current_state; + + default: + Next_state = State_idle; + endcase + +always @( posedge Reset or posedge Clk ) + if ( Reset ) + IFG_counter <= 0; + else if ( Current_state!=State_IFG ) + IFG_counter <= 0; + else + IFG_counter <= IFG_counter + 1; + +//****************************************************************************** +//gen fifo interface signals +//****************************************************************************** + +assign pre_fifo_wrdata = RxD_dl1; + +always @( Current_state ) + if ( Current_state==State_data ) + pre_fifo_data_en = 1; + else + pre_fifo_data_en = 0; + +always @( Current_state ) + if ( (Current_state==State_ErrEnd ) || + (Current_state==State_OkEnd ) || + (Current_state==State_CRCErrEnd ) || + (Current_state==State_FFFullErrEnd) || + (Current_state==State_DropEnd ) || + (Current_state==State_Drop2End ) ) + pre_fifo_data_end = 1; + else + pre_fifo_data_end = 0; + +always @( Current_state ) + if ( (Current_state==State_ErrEnd ) || + (Current_state==State_CRCErrEnd ) || + (Current_state==State_FFFullErrEnd) || + (Current_state==State_DropEnd ) || + (Current_state==State_Drop2End ) ) + pre_fifo_data_err = 1; + else + pre_fifo_data_err = 0; + +always @( Current_state ) + if ( (Current_state==State_DropEnd ) || + (Current_state==State_Drop2End) ) + pre_fifo_data_drop = 1; + else + pre_fifo_data_drop = 0; + + // Drop in main Rx FIFO is no longer supported! + assign Fifo_data_drop = 0; + +//****************************************************************************** +//CRC_chk interface +//****************************************************************************** + +always @(Current_state) + if (Current_state==State_data) + CRC_en =1; + else + CRC_en =0; + +always @(Current_state) + if (Current_state==State_SFD) + CRC_init =1; + else + CRC_init =0; + +//****************************************************************************** +//gen rmon signals +//****************************************************************************** +always @ (posedge Clk or posedge Reset) + if (Reset) + Frame_length_counter <=0; + else if (Current_state==State_SFD) + Frame_length_counter <=1; + else if (Current_state==State_data) + Frame_length_counter <=Frame_length_counter+ 1'b1; + +always @( Frame_length_counter ) + if ( Frame_length_counter < 8 ) + ProcessingHeader = 1; + else + ProcessingHeader = 0; + +always @ (Frame_length_counter or RX_MIN_LENGTH) + if (Frame_length_counterRX_MAX_LENGTH) + Too_long =1; + else + Too_long =0; + +assign Rx_pkt_length_rmon = Frame_length_counter-1'b1; + +reg [2:0] Rx_apply_rmon_reg; + +always @( posedge Clk or posedge Reset ) + if ( Reset ) + begin + Rx_apply_rmon <= 0; + Rx_apply_rmon_reg <= 'b0; + end + else + begin + if ( (Current_state==State_OkEnd ) || + (Current_state==State_ErrEnd ) || + (Current_state==State_CRCErrEnd ) || + (Current_state==State_Drop2End ) || + (Current_state==State_FFFullErrEnd) ) + Rx_apply_rmon <= 1; + else + if ( Rx_apply_rmon_reg[2] ) + Rx_apply_rmon <= 0; + + Rx_apply_rmon_reg <= { Rx_apply_rmon_reg[1:0], Rx_apply_rmon }; + end + +always @ (posedge Clk or posedge Reset) + if (Reset) + Rx_pkt_err_type_rmon <=0; + else if (Current_state==State_CRCErrEnd) + Rx_pkt_err_type_rmon <=3'b001 ;// + else if (Current_state==State_FFFullErrEnd) + Rx_pkt_err_type_rmon <=3'b010 ;// + else if ( (Current_state==State_ErrEnd) || (Current_state==State_Drop2End) ) + Rx_pkt_err_type_rmon <=3'b011 ;// + else if(Current_state==State_OkEnd) + Rx_pkt_err_type_rmon <=3'b100 ; + + + +always @ (posedge Clk or posedge Reset) + if (Reset) + Rx_pkt_type_rmon <=0; + else if (Current_state==State_OkEnd&&pause_frame_ptr) + Rx_pkt_type_rmon <=3'b100 ;// + else if(Current_state==State_SFD&&Next_state==State_data) + Rx_pkt_type_rmon <={1'b0,MRxD[7:6]}; + +always @ (posedge Clk or posedge Reset) + if (Reset) + broadcast_ptr <=0; + else if(Current_state==State_IFG) + broadcast_ptr <=0; + else if(Current_state==State_SFD&&Next_state==State_data&&MRxD[7:6]==2'b11) + broadcast_ptr <=1; + + + +//****************************************************************************** +//MAC add checker signals +//****************************************************************************** +always @ (Frame_length_counter or pre_fifo_data_en) + if(Frame_length_counter>=1&&Frame_length_counter<=6) + MAC_add_en <=pre_fifo_data_en; + else + MAC_add_en <=0; + +//****************************************************************************** +//flow control signals +//****************************************************************************** +always @ (posedge Clk or posedge Reset) + if (Reset) + Pause_current <=Pause_idle; + else + Pause_current <=Pause_next; + +always @ (*) + case (Pause_current) + Pause_idle : + if(Current_state==State_SFD) + Pause_next =Pause_pre_syn; + else + Pause_next =Pause_current; + Pause_pre_syn: + case (Frame_length_counter) + 16'd1: if (RxD_dl1==8'h01) + Pause_next =Pause_current; + else + Pause_next =Pause_idle; + 16'd2: if (RxD_dl1==8'h80) + Pause_next =Pause_current; + else + Pause_next =Pause_idle; + 16'd3: if (RxD_dl1==8'hc2) + Pause_next =Pause_current; + else + Pause_next =Pause_idle; + 16'd4: if (RxD_dl1==8'h00) + Pause_next =Pause_current; + else + Pause_next =Pause_idle; + 16'd5: if (RxD_dl1==8'h00) + Pause_next =Pause_current; + else + Pause_next =Pause_idle; + 16'd6: if (RxD_dl1==8'h01) + Pause_next =Pause_current; + else + Pause_next =Pause_idle; + 16'd13: if (RxD_dl1==8'h88) + Pause_next =Pause_current; + else + Pause_next =Pause_idle; + 16'd14: if (RxD_dl1==8'h08) + Pause_next =Pause_current; + else + Pause_next =Pause_idle; + 16'd15: if (RxD_dl1==8'h00) + Pause_next =Pause_current; + else + Pause_next =Pause_idle; + 16'd16: if (RxD_dl1==8'h01) + Pause_next =Pause_quanta_hi; + else + Pause_next =Pause_idle; + default: Pause_next =Pause_current; + endcase + Pause_quanta_hi : + Pause_next =Pause_quanta_lo; + Pause_quanta_lo : + Pause_next =Pause_syn; + Pause_syn : + if (Current_state==State_IFG) + Pause_next =Pause_idle; + else + Pause_next =Pause_current; + default + Pause_next =Pause_idle; + endcase + +always @ (posedge Clk or posedge Reset) + if (Reset) + pause_quanta_h <=0; + else if(Pause_current==Pause_quanta_hi) + pause_quanta_h <=RxD_dl1; + +always @ (posedge Clk or posedge Reset) + if (Reset) + pause_quanta <=0; + else if(Pause_current==Pause_quanta_lo) + pause_quanta <={pause_quanta_h,RxD_dl1}; + + // The following 2 always blocks are a strange way of holding + // pause_quanta_val high for 2 cycles +always @ (posedge Clk or posedge Reset) + if (Reset) + pause_quanta_val_tmp <=0; + else if(Current_state==State_OkEnd&&Pause_current==Pause_syn) + pause_quanta_val_tmp <=1; + else + pause_quanta_val_tmp <=0; + +always @ (posedge Clk or posedge Reset) + if (Reset) + pause_quanta_val <=0; + else if(Current_state==State_OkEnd&&Pause_current==Pause_syn||pause_quanta_val_tmp) + pause_quanta_val <=1; + else + pause_quanta_val <=0; + +always @ (posedge Clk or posedge Reset) + if (Reset) + pause_frame_ptr <=0; + else if(Pause_current==Pause_syn) + pause_frame_ptr <=1; + else + pause_frame_ptr <=0; + +endmodule + + -- cgit v1.2.3