////////////////////////////////////////////////////////////////////// //// //// //// MAC_top.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_top #(parameter TX_FF_DEPTH = 9, parameter RX_FF_DEPTH = 9) ( // System signals input Clk_125M, input Clk_user, input rst_mac, input rst_user, // Wishbone compliant core host interface input RST_I, // Active high (async) reset of the Wishbone interface input CLK_I, // Wishbone interface clock (nominally 50 MHz) input STB_I, // Active high module-select input CYC_I, // Active high cycle-enable input [6:0] ADR_I, // Module register address input WE_I, // Active high for writes, low for reads input [31:0] DAT_I, // Write data output [31:0] DAT_O, // Read data output ACK_O, // Acknowledge output – single high pulse // User (packet) 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, output Tx_mac_wa, input Tx_mac_wr, input [31:0] Tx_mac_data, input [1:0] Tx_mac_BE, input Tx_mac_sop, input Tx_mac_eop, // PHY interface (GMII/MII) output Gtx_clk, // Used only in GMII mode input Rx_clk, input Tx_clk, // Used only in MII mode output Tx_er, output Tx_en, output [7:0] Txd, input Rx_er, input Rx_dv, input [7:0] Rxd, input Crs, input Col, // MDIO interface (to PHY) inout Mdio, output Mdc, // FIFO levels output [15:0] rx_fifo_occupied, output rx_fifo_full, output rx_fifo_empty, output [15:0] tx_fifo_occupied, output tx_fifo_full, output tx_fifo_empty, // Debug Interface output [31:0] debug0, output [31:0] debug1 ); wire rst_mac_rx = rst_mac; wire rst_mac_tx = rst_mac; wire [2:0] Speed; wire [31:0] debug_rx; wire [31:0] debug_tx0; wire [31:0] debug_tx1; //------------------------------------------------------------------------- // Local declarations //------------------------------------------------------------------------- // RMON interface wire [15:0] Rx_pkt_length_rmon; wire Rx_apply_rmon; wire [2:0] Rx_pkt_err_type_rmon; wire [2:0] Rx_pkt_type_rmon; wire [2:0] Tx_pkt_type_rmon; wire [15:0] Tx_pkt_length_rmon; wire Tx_apply_rmon; wire [2:0] Tx_pkt_err_type_rmon; // PHY interface wire MCrs_dv; wire [7:0] MRxD; wire MRxErr; // Flow-control signals wire [15:0] pause_quanta; wire pause_quanta_val; wire [15:0] rx_fifo_space; wire pause_apply, pause_quanta_sub; wire xon_gen, xoff_gen, xon_gen_complete, xoff_gen_complete; wire [15:0] fc_hwmark, fc_lwmark; //PHY interface wire [7:0] MTxD; wire MTxEn; wire MCRS; // Interface clk signals wire MAC_tx_clk; wire MAC_rx_clk; wire MAC_tx_clk_div; wire MAC_rx_clk_div; // Reg signals wire [4:0] Tx_Hwmark; wire [4:0] Tx_Lwmark; wire pause_frame_send_en; wire [15:0] pause_quanta_set; wire MAC_tx_add_en; wire FullDuplex; wire [3:0] MaxRetry; wire [5:0] IFGset; wire [7:0] MAC_tx_add_prom_data; wire [2:0] MAC_tx_add_prom_add; wire MAC_tx_add_prom_wr; wire tx_pause_en; // Rx host interface wire MAC_rx_add_chk_en; wire [7:0] MAC_rx_add_prom_data; wire [2:0] MAC_rx_add_prom_add; wire MAC_rx_add_prom_wr; wire broadcast_filter_en; wire RX_APPEND_CRC; wire [4:0] Rx_Hwmark; wire [4:0] Rx_Lwmark; wire CRC_chk_en; wire [5:0] RX_IFG_SET; wire [15:0] RX_MAX_LENGTH; wire [6:0] RX_MIN_LENGTH; // RMON host interface wire [5:0] CPU_rd_addr; wire CPU_rd_apply; wire CPU_rd_grant; wire [31:0] CPU_rd_dout; // PHY int host interface wire Line_loop_en; // MII to CPU wire [7:0] Divider; wire [15:0] CtrlData; wire [4:0] Rgad; wire [4:0] Fiad; wire NoPre; wire WCtrlData; wire RStat; wire ScanStat; wire Busy; wire LinkFail; wire Nvalid; wire [15:0] Prsd; wire WCtrlDataStart; wire RStatStart; wire UpdateMIIRX_DATAReg; wire [15:0] broadcast_bucket_depth; wire [15:0] broadcast_bucket_interval; //------------------------------------------------------------------------- // Instantiation of sub-modules //------------------------------------------------------------------------- MAC_rx #(.RX_FF_DEPTH(RX_FF_DEPTH)) U_MAC_rx( .Reset ( rst_mac_rx ), .Clk_user ( Clk_user ), .Clk ( MAC_rx_clk_div ), // RMII interface .MCrs_dv ( MCrs_dv ), .MRxD ( MRxD ), .MRxErr ( MRxErr ), // Flow-control signals .pause_quanta ( pause_quanta ), .pause_quanta_val ( pause_quanta_val ), .rx_fifo_space ( rx_fifo_space ), // User interface .Rx_mac_empty ( Rx_mac_empty ), .Rx_mac_rd ( Rx_mac_rd ), .Rx_mac_data ( Rx_mac_data ), .Rx_mac_BE ( Rx_mac_BE ), .Rx_mac_sop ( Rx_mac_sop ), .Rx_mac_eop ( Rx_mac_eop ), .Rx_mac_err ( Rx_mac_err ), // CPU .MAC_rx_add_chk_en ( MAC_rx_add_chk_en ), .MAC_add_prom_data ( MAC_rx_add_prom_data ), .MAC_add_prom_add ( MAC_rx_add_prom_add ), .MAC_add_prom_wr ( MAC_rx_add_prom_wr ), .broadcast_filter_en ( broadcast_filter_en ), .broadcast_bucket_depth ( broadcast_bucket_depth ), .broadcast_bucket_interval( broadcast_bucket_interval ), .RX_APPEND_CRC ( RX_APPEND_CRC ), .Rx_Hwmark ( Rx_Hwmark ), .Rx_Lwmark ( Rx_Lwmark ), .CRC_chk_en ( CRC_chk_en ), .RX_IFG_SET ( RX_IFG_SET ), .RX_MAX_LENGTH ( RX_MAX_LENGTH ), .RX_MIN_LENGTH ( RX_MIN_LENGTH ), // RMON interface .Rx_pkt_length_rmon ( Rx_pkt_length_rmon ), .Rx_apply_rmon ( Rx_apply_rmon ), .Rx_pkt_err_type_rmon ( Rx_pkt_err_type_rmon ), .Rx_pkt_type_rmon ( Rx_pkt_type_rmon ), .rx_fifo_occupied(rx_fifo_occupied), .rx_fifo_full(rx_fifo_full), .rx_fifo_empty(rx_fifo_empty), .debug(debug_rx) ); MAC_tx #(.TX_FF_DEPTH(TX_FF_DEPTH)) U_MAC_tx( .Reset ( rst_mac_tx ), .Clk ( MAC_tx_clk_div ), //.Clk_user ( Clk_user ), .Clk_user ( MAC_tx_clk_div ), // PHY interface .TxD ( MTxD ), .TxEn ( MTxEn ), .CRS ( MCRS ), // RMON .Tx_pkt_type_rmon ( Tx_pkt_type_rmon ), .Tx_pkt_length_rmon ( Tx_pkt_length_rmon ), .Tx_apply_rmon ( Tx_apply_rmon ), .Tx_pkt_err_type_rmon( Tx_pkt_err_type_rmon ), // User interface .Tx_mac_wa ( Tx_mac_wa ), .Tx_mac_wr ( Tx_mac_wr ), .Tx_mac_data ( Tx_mac_data ), .Tx_mac_BE ( Tx_mac_BE ), .Tx_mac_sop ( Tx_mac_sop ), .Tx_mac_eop ( Tx_mac_eop ), // Host interface .Tx_Hwmark ( Tx_Hwmark ), .Tx_Lwmark ( Tx_Lwmark ), .MAC_tx_add_en ( MAC_tx_add_en ), .FullDuplex ( FullDuplex ), .MaxRetry ( MaxRetry ), .IFGset ( IFGset ), .MAC_add_prom_data ( MAC_tx_add_prom_data ), .MAC_add_prom_add ( MAC_tx_add_prom_add ), .MAC_add_prom_wr ( MAC_tx_add_prom_wr ), .pause_apply ( pause_apply ), .pause_quanta_sub ( pause_quanta_sub ), .pause_quanta_set ( pause_quanta_set ), .xoff_gen ( xoff_gen ), .xon_gen ( xon_gen ), .xoff_gen_complete ( xoff_gen_complete ), .xon_gen_complete ( xon_gen_complete ), .debug0(debug_tx0), .debug1(debug_tx1) ); // Flow control outbound -- when other side sends PAUSE, we wait flow_ctrl_tx flow_ctrl_tx (.rst(rst_mac_tx), .tx_clk(MAC_tx_clk_div), // Setting .tx_pause_en ( tx_pause_en ), // From RX side .pause_quanta (pause_quanta), .pause_quanta_val(pause_quanta_val), // Other guy sent a PAUSE // To TX side .pause_apply (pause_apply), // To TX, stop sending new frames .pause_quanta_sub (pause_quanta_sub) // From TX, indicates we have used up 1 quanta ); flow_ctrl_rx flow_ctrl_rx // When we are running out of RX space, send a PAUSE (.rst(rst_mac_rx), // FIXME // Settings .pause_frame_send_en ( pause_frame_send_en ), .pause_quanta_set ( pause_quanta_set ), .fc_hwmark (fc_hwmark), .fc_lwmark (fc_lwmark), // From RX side .rx_clk(MAC_rx_clk_div), .rx_fifo_space (rx_fifo_space), // Decide if we need to send a PAUSE // To TX side .tx_clk(MAC_tx_clk_div), .xoff_gen (xoff_gen), .xon_gen(xon_gen), // Tell our TX to send PAUSE frames .xoff_gen_complete (xoff_gen_complete), .xon_gen_complete(xon_gen_complete) ); RMON U_RMON( .Clk ( CLK_I ), .Reset ( RST_I ), // Tx RMON .Tx_pkt_type_rmon ( Tx_pkt_type_rmon ), .Tx_pkt_length_rmon ( Tx_pkt_length_rmon ), .Tx_apply_rmon ( Tx_apply_rmon ), .Tx_pkt_err_type_rmon( Tx_pkt_err_type_rmon ), // Rx RMON .Rx_pkt_type_rmon ( Rx_pkt_type_rmon ), .Rx_pkt_length_rmon ( Rx_pkt_length_rmon ), .Rx_apply_rmon ( Rx_apply_rmon ), .Rx_pkt_err_type_rmon( Rx_pkt_err_type_rmon ), // CPU .CPU_rd_addr ( CPU_rd_addr ), .CPU_rd_apply ( CPU_rd_apply ), .CPU_rd_grant ( CPU_rd_grant ), .CPU_rd_dout ( CPU_rd_dout ) ); Phy_int U_Phy_int( .rst_mac_rx ( rst_mac_rx ), .rst_mac_tx ( rst_mac_tx ), .MAC_rx_clk ( MAC_rx_clk ), .MAC_tx_clk ( MAC_tx_clk ), // Rx interface .MCrs_dv ( MCrs_dv ), .MRxD ( MRxD ), .MRxErr ( MRxErr ), // Tx interface .MTxD ( MTxD ), .MTxEn ( MTxEn ), .MCRS ( MCRS ), // PHY interface .Tx_er ( Tx_er ), .Tx_en ( Tx_en ), .Txd ( Txd ), .Rx_er ( Rx_er ), .Rx_dv ( Rx_dv ), .Rxd ( Rxd ), .Crs ( Crs ), .Col ( Col ), // Host interface .Line_loop_en( Line_loop_en ), .Speed ( Speed ) ); Clk_ctrl U_Clk_ctrl( .Reset ( rst_mac ), .Clk_125M ( Clk_125M ), // Host interface .Speed ( Speed ), // Phy interface .Gtx_clk ( Gtx_clk ), .Rx_clk ( Rx_clk ), .Tx_clk ( Tx_clk ), // Interface clocks .MAC_tx_clk ( MAC_tx_clk ), .MAC_rx_clk ( MAC_rx_clk ), .MAC_tx_clk_div( MAC_tx_clk_div ), .MAC_rx_clk_div( MAC_rx_clk_div ) ); eth_miim U_eth_miim( .Clk ( CLK_I ), .Reset ( RST_I ), .Divider ( Divider ), .NoPre ( NoPre ), .CtrlData ( CtrlData ), .Rgad ( Rgad ), .Fiad ( Fiad ), .WCtrlData ( WCtrlData ), .RStat ( RStat ), .ScanStat ( ScanStat ), .Mdio ( Mdio ), .Mdc ( Mdc ), .Busy ( Busy ), .Prsd ( Prsd ), .LinkFail ( LinkFail ), .Nvalid ( Nvalid ), .WCtrlDataStart ( WCtrlDataStart ), .RStatStart ( RStatStart ), .UpdateMIIRX_DATAReg( UpdateMIIRX_DATAReg ) ); Reg_int U_Reg_int( // Wishbone compliant core host interface .CLK_I( CLK_I ), .RST_I( RST_I ), .STB_I( STB_I ), .CYC_I( CYC_I ), .ADR_I( ADR_I ), .WE_I ( WE_I ), .DAT_I( DAT_I ), .DAT_O( DAT_O ), .ACK_O( ACK_O ), // Tx host interface .Tx_Hwmark ( Tx_Hwmark ), .Tx_Lwmark ( Tx_Lwmark ), .MAC_tx_add_en ( MAC_tx_add_en ), .FullDuplex ( FullDuplex ), .MaxRetry ( MaxRetry ), .IFGset ( IFGset ), .MAC_tx_add_prom_data ( MAC_tx_add_prom_data ), .MAC_tx_add_prom_add ( MAC_tx_add_prom_add ), .MAC_tx_add_prom_wr ( MAC_tx_add_prom_wr ), // Rx host interface .MAC_rx_add_chk_en ( MAC_rx_add_chk_en ), .MAC_rx_add_prom_data ( MAC_rx_add_prom_data ), .MAC_rx_add_prom_add ( MAC_rx_add_prom_add ), .MAC_rx_add_prom_wr ( MAC_rx_add_prom_wr ), .broadcast_filter_en ( broadcast_filter_en ), .broadcast_bucket_depth ( broadcast_bucket_depth ), .broadcast_bucket_interval( broadcast_bucket_interval ), .RX_APPEND_CRC ( RX_APPEND_CRC ), .Rx_Hwmark ( Rx_Hwmark ), .Rx_Lwmark ( Rx_Lwmark ), .CRC_chk_en ( CRC_chk_en ), .RX_IFG_SET ( RX_IFG_SET ), .RX_MAX_LENGTH ( RX_MAX_LENGTH ), .RX_MIN_LENGTH ( RX_MIN_LENGTH ), // Flow Control settings .pause_frame_send_en ( pause_frame_send_en ), .pause_quanta_set ( pause_quanta_set ), .tx_pause_en ( tx_pause_en ), .fc_hwmark ( fc_hwmark ), .fc_lwmark ( fc_lwmark ), // RMON host interface .CPU_rd_addr ( CPU_rd_addr ), .CPU_rd_apply ( CPU_rd_apply ), .CPU_rd_grant ( CPU_rd_grant ), .CPU_rd_dout ( CPU_rd_dout ), // PHY int host interface .Line_loop_en ( Line_loop_en ), .Speed ( Speed ), // MII to CPU .Divider ( Divider ), .CtrlData ( CtrlData ), .Rgad ( Rgad ), .Fiad ( Fiad ), .NoPre ( NoPre ), .WCtrlData ( WCtrlData ), .RStat ( RStat ), .ScanStat ( ScanStat ), .Busy ( Busy ), .LinkFail ( LinkFail ), .Nvalid ( Nvalid ), .Prsd ( Prsd ), .WCtrlDataStart ( WCtrlDataStart ), .RStatStart ( RStatStart ), .UpdateMIIRX_DATAReg ( UpdateMIIRX_DATAReg ) ); assign debug0 = {xon_gen, xoff_gen, Tx_en, Rx_dv}; //assign debug0 = {{debug_rx[3:0], xon_gen, xon_gen_complete, xoff_gen, xoff_gen_complete}, // {1'b0,Rx_mac_err,Rx_mac_empty,Rx_mac_rd,Rx_mac_sop,Rx_mac_eop,Rx_mac_BE[1:0]}, // {rx_fifo_space}}; //assign debug0 = debug_tx0; //assign debug1 = debug_tx1; endmodule