fpga_feixiang 发表于 2017-4-26 15:59:55

千兆以太网 TCP, UDP协议, FPGA实现

这个工程由几部分组成, 外部使用了88e1111千兆以太网phy。FPGA内部有几个大的模块,

顶层模块:

    //////////////////////////////////////////////////////////////////////
    ////                                                            ////
    ////tcpip_hw                                                    ////
    ////                                                            ////
    ////Description                                                 ////
    ////      top module                                              ////
    ////                                                            ////
    ////Author(s):                                                ////
    ////      - bin qiu, qiubin@opencores.org orchat1@126.com       ////
    ////                                                            ////
    ////                   Copyright (C) 2015                         ////
    //////////////////////////////////////////////////////////////////////
    `include "tcpip_hw_defines.sv"
      
    module tcpip_hw(      
      input clk,
      input rst_n,
         
      output mdc,
      inoutmdio,
      output phy_rst_n,
      output is_link_up,
      
      input rx_data,
      output logic tx_data,
      
      input rx_clk,
      input rx_data_valid,
      output logic gtx_clk,
      inputtx_clk,   
      output logic tx_en,
         
//user interface
      input wr_data,   
      input wr_clk,   
      input wr_en,   
      output wr_full,   
      
      output rd_data,   
      input rd_clk,   
      input rd_en,   
      output rd_empty
    );
      
    wire clk8;
    wire clk50;
    wire clk125;
    wire clk125out;
    wire is_1000m;
    logic eth_mode;
      
      
    always @(posedge clk50)
      eth_mode <= is_1000m;
         
    assign gtx_clk = clk125out;
      
      
    pll pll_inst(
      .inclk0(clk),
      .c0(clk50),
      .c1(clk125out),
      .c2(clk8)
    );
      
    wire mdio_out;
    wire mdio_oe;
    wire reset_n;
      
    assign mdio = mdio_oe == 1'b1 ? mdio_out : 1'bz;   
    rst_ctrl rst_ctrl_inst(
      .ext_rst(rst_n),
      .rst(reset_n),
      .clk(clk50)   
    );
      
    wire is_100m;
    wire is_10m;
      
    wire tse_addr;
    wire tse_wr;
    wire tse_wr_data;
    wire tse_rd;
    wire tse_rd_data;
    wire tse_busy;
      
      
    headers_if if_headers_rx(clk50);
    headers_if if_headers_tx(clk50);
    ff_tx_if if_tx(clk50);
    ff_rx_if if_rx(clk50);
      
    frame_type_t rx_type;
    frame_type_t tx_type;
      
    logic rx_done;
    logic data_recv;
    logic data_recv_len;
    logic data_recv_valid;
    logic data_recv_start;
    logic rx_done_clear;
    u32_t cur_ripaddr;
    u16_t cur_rport;
    u16_t rx_header_checksum;
    logic need_ack;
    logic flags;
      
    logic tx_start;
    logic tx_dword_count;
    logic fifo_rdreq;
    logic fifo_q;
    logic fifo_empty;
    logic pkt_send_eop;
    logic data_send_len;
      
    logic wr_addr_synced;
    rx_ram_in_if if_rx_ram_in();
    rx_ram_out_if if_rx_ram_out();
    tx_ram_out_if if_tx_ram_out();
    tx_ram_in_if if_tx_ram_in();
      
    logic local_ipaddr;
    logic remote_ipaddr;
    logic remote_port_local_port;
    logic op_mode;
    logic init_done;
    simple_mac_top simple_mac_top(   
      .clk(clk50),
      .rst_n(reset_n),
         
      .mdc(mdc),
      .mdio_in(mdio),
      .mdio_out(mdio_out),
      .mdio_oe(mdio_oe),
      .phy_rst_n(phy_rst_n),
      .eth_mode(eth_mode),
         
      .rx_data(rx_data),
      .tx_data(tx_data),
      .rx_clk(rx_clk),
      .tx_clk(tx_clk),
      .clk125out(clk125out),
      .rx_data_valid(rx_data_valid),
      .tx_en(tx_en),
      .reg_addr(tse_addr),
      .reg_wr(tse_wr),
      .reg_wr_data(tse_wr_data),
      .reg_rd(tse_rd),
      .reg_rd_data(tse_rd_data),
      .reg_busy(tse_busy),
         
      .ff_rx_clk(clk50),
      .ff_rx_data(if_rx.ff_rx_data),
      .ff_rx_eop(if_rx.ff_rx_eop),
      .ff_rx_sop(if_rx.ff_rx_sop),
      .rx_err(if_rx.rx_err),
      .ff_rx_dval(if_rx.ff_rx_dval),
      .ff_rx_rdy(if_rx.ff_rx_rdy),
      
      .ff_tx_clk(clk50),
      .ff_tx_data(if_tx.ff_tx_data),
      .ff_tx_eop(if_tx.ff_tx_eop),
      .ff_tx_sop(if_tx.ff_tx_sop),
      .ff_tx_wren(if_tx.ff_tx_wren),
      .ff_tx_rdy(if_tx.ff_tx_rdy),
      .*
    );
      
      
    data_source data_source_inst(
      .rst_n(reset_n),
      .wr_data(wr_data),
      .wr_clk(wr_clk),
      .wr_en(wr_en),
      .wr_full(wr_full),
      
      .rd_data(rd_data),
      .rd_clk(rd_clk),
      .rd_en(rd_en),
      .rd_empty(rd_empty),
         
      .*
    );
      
    rx_ram rx_ram_inst(
      .rst_n(reset_n),
      .*
    );
      
    tx_ram tx_ram_inst(
      .rst_n(reset_n),
      .overflow_flag(),
      .in_flush(),
      .*
    );
      
    mac_config mac_config_inst (
      .clk(clk50),
      .rst_n(reset_n),
      .*
    );
      
    assign pkt_send_eop = if_tx.ff_tx_eop;
    logic next_parse_state;
      
      
    mac_rx_path mac_rx_path_inst(
      .rst_n(reset_n),
      .*
    );
      
    mac_tx_pathmac_tx_path_inst (
      .rst_n(reset_n),
         .next_state(),
      .*
    );
      
    eth_fsm eth_fsm_inst(
      .clk(clk50),
      .rst_n(reset_n),
      .state_counter(),
       .*
    );
      
    endmodule

1.与外部phy芯片通信的模块,simple_mac模块。主要功能是通过mdio配置phy, 给发送帧打包(加入preamble,padding和crc32),和接收帧解包。 下面是顶层代码:
    //////////////////////////////////////////////////////////////////////
    ////                                                            ////
    ////simple_mac_top                                              ////
    ////                                                            ////
    ////Description                                                 ////
    ////      top module of simple mac                              ////
    ////                                                            ////
    ////Author(s):                                                ////
    ////      - bin qiu, qiubin@opencores.org orchat1@126.com       ////
    ////                                                            ////
    ////                   Copyright (C) 2015                         ////
    //////////////////////////////////////////////////////////////////////
      
      
    module simple_mac_top(   
      input clk,
      input rst_n,
         
      output mdc,
      inputmdio_in,
      output mdio_out,
      output mdio_oe,
      output phy_rst_n,
      
      input rx_data,
      output logic tx_data,
         
      input eth_mode,
      input rx_clk,
      input tx_clk,
      input clk125out,
      output tx_en,
      inputrx_data_valid,
      
      input reg_addr,
      input reg_wr,
      input reg_wr_data,
      input reg_rd,
      output reg_rd_data,
      output reg_busy,
         
      inputff_rx_clk,
      output ff_rx_data,
      output ff_rx_eop,
      output ff_rx_sop,
      output rx_err,
      output ff_rx_dval,
      inputff_rx_rdy,
      
      input ff_tx_clk,
      input ff_tx_data,
      input ff_tx_eop,
      input ff_tx_sop,
      input ff_tx_wren,
      output ff_tx_rdy
    );
    assign phy_rst_n = rst_n;
      
    wire rx_data_mac;
    wire rx_data_valid_mac;
    wire rx_sop_mac;
    wire tx_data_valid_mac;
    wire tx_data_mac;
      
      
    wire ff_tx_data0;
    wire ff_tx_eop0;
    wire ff_tx_sop0;
    wire ff_tx_wren0;
      
    wire ff_rx_data0;
    wire ff_rx_eop0;
    wire ff_rx_sop0;
    wire ff_rx_dval0;
      
    wire tx_data_en;
      
    tx_header_align32 tx_header_align32_inst(
      .ff_tx_clk(ff_tx_clk),
      .rst_n(rst_n),
      .ff_tx_data0(ff_tx_data),
      .ff_tx_eop0(ff_tx_eop),
      .ff_tx_sop0(ff_tx_sop),
      .ff_tx_wren0(ff_tx_wren),
      
      .ff_tx_data(ff_tx_data0),
      .ff_tx_eop(ff_tx_eop0),
      .ff_tx_sop(ff_tx_sop0),
      .ff_tx_wren(ff_tx_wren0)
    );
      
      
    rx_header_align32 rx_header_align32_inst(
      .ff_rx_clk(ff_rx_clk),
      .rst_n(rst_n),
      .ff_rx_data0(ff_rx_data0),
      .ff_rx_eop0(ff_rx_eop0),
      .ff_rx_sop0(ff_rx_sop0),
      .ff_rx_dval0(ff_rx_dval0),
      
      .ff_rx_data(ff_rx_data),
      .ff_rx_eop(ff_rx_eop),
      .ff_rx_sop(ff_rx_sop),
      .ff_rx_dval(ff_rx_dval)
    );
    wire mac_tx_clk;
      
    assign mac_tx_clk = clk125out;
      
    simple_mac_rx_gmii rx_gmii_inst(
      .rx_clk(rx_clk),
      .rst_n(rst_n),
      .eth_mode(eth_mode),
      .rx_data(rx_data),
      .rx_data_valid(rx_data_valid),
      
      .rx_data_mac(rx_data_mac),
      .rx_data_valid_mac(rx_data_valid_mac),
      .rx_sop_mac(rx_sop_mac)
    );
      
    simple_mac_tx_gmii gmii_tx_inst(
      .rst_n(rst_n),
      .eth_mode(eth_mode),
      .tx_data_mac(tx_data_mac),
      .tx_data_valid_mac(tx_data_valid_mac),
      .tx_data_en(tx_data_en),
      
      .tx_clk(mac_tx_clk),
      .tx_en(tx_en),
      .tx_data(tx_data)
    );
      
    logic mac_addr;
    simple_mac_rx_path simple_mac_rx_path_inst(
      .rx_clk(rx_clk),
      .rst_n(rst_n),
      .mac_addr(mac_addr),
      .rx_data_mac(rx_data_mac),
      .rx_data_valid_mac(rx_data_valid_mac),
      .rx_sop_mac(rx_sop_mac),
      
       .ff_rx_clk(ff_rx_clk),
       .ff_rx_data(ff_rx_data0),
       .ff_rx_eop(ff_rx_eop0),
       .ff_rx_sop(ff_rx_sop0),
       .rx_err(rx_err),
       .ff_rx_dval(ff_rx_dval0),
       .ff_rx_rdy(ff_rx_rdy)
    );
      
    simple_mac_tx_path simple_mac_tx_path_inst(
      .ff_tx_clk(ff_tx_clk),
      .rst_n(rst_n),
      .eth_mode(eth_mode),
      .ff_tx_data(ff_tx_data0),
      .ff_tx_eop(ff_tx_eop0),
      .ff_tx_sop(ff_tx_sop0),
      .ff_tx_wren(ff_tx_wren0),
      .ff_tx_rdy(ff_tx_rdy),
      
      .tx_clk_mac(mac_tx_clk),
      .tx_data_mac(tx_data_mac),
      .tx_data_valid_mac(tx_data_valid_mac),
      .tx_data_en(tx_data_en),
      .pkt_send_num()
      
    );
      
    wire mdio_busy;
    wire mdio_rd_data;
    simple_mac_phy_mdio phy_mdio(
      .clk(clk),
      .rst_n(rst_n),
      .mdc(mdc),
      .mdin(mdio_in),
      .mdout(mdio_out),
      .mdoe(mdio_oe),
      
      .phy_addr(5'b10000),
      .data_in(reg_wr_data),
      .reg_addr(reg_addr),
      .wr(reg_wr),
      .rd(reg_rd),
      .data_out(mdio_rd_data),
      .busy(mdio_busy)      
    );
      
    wire regs_rd_data;
    wire regs_busy;
    simple_mac_regs simple_mac_regs_inst(
      .clk(clk),
      .rst_n(rst_n),
      .data_in(reg_wr_data),
      .reg_addr(reg_addr),
      .wr(reg_wr),
      .rd(reg_rd),
      .data_out(regs_rd_data),
      .busy(regs_busy),
      
      .mac_addr(mac_addr),
      .*
    );
      
    simple_mac_bus_arb simple_mac_bus_arb_inst(
      .reg_addr(reg_addr),      
      .mdio_busy(mdio_busy),
      .mdio_rd_data(mdio_rd_data),
      .regs_busy(regs_busy),
      .regs_rd_data(regs_rd_data),
      .reg_busy(reg_busy),
      .reg_rd_data(reg_rd_data)
    );
      
      
    endmodule
页: [1]
查看完整版本: 千兆以太网 TCP, UDP协议, FPGA实现