|
这个工程由几部分组成, 外部使用了88e1111千兆以太网phy。FPGA内部有几个大的模块,
顶层模块:
//////////////////////////////////////////////////////////////////////
//// ////
//// tcpip_hw ////
//// ////
//// Description ////
//// top module ////
//// ////
//// Author(s): ////
//// - bin qiu, qiubin@opencores.org or chat1@126.com ////
//// ////
//// Copyright (C) 2015 ////
//////////////////////////////////////////////////////////////////////
`include "tcpip_hw_defines.sv"
module tcpip_hw(
input clk,
input rst_n,
output mdc,
inout mdio,
output phy_rst_n,
output is_link_up,
input [7:0] rx_data,
output logic [7:0] tx_data,
input rx_clk,
input rx_data_valid,
output logic gtx_clk,
input tx_clk,
output logic tx_en,
//user interface
input [7:0] wr_data,
input wr_clk,
input wr_en,
output wr_full,
output [7:0] 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 [7:0] tse_addr;
wire tse_wr;
wire [31:0] tse_wr_data;
wire tse_rd;
wire [31:0] 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 [31:0] data_recv;
logic [15:0] 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 [7:0] flags;
logic tx_start;
logic [13:0] tx_dword_count;
logic fifo_rdreq;
logic [31:0] fifo_q;
logic fifo_empty;
logic pkt_send_eop;
logic [15:0] data_send_len;
logic [10:0] 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 [31:0] local_ipaddr;
logic [31:0] remote_ipaddr;
logic [31:0] remote_port_local_port;
logic [1:0] 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[7:0]),
.tx_data(tx_data[7:0]),
.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 [3:0] next_parse_state;
mac_rx_path mac_rx_path_inst(
.rst_n(reset_n),
.*
);
mac_tx_path mac_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 or chat1@126.com ////
//// ////
//// Copyright (C) 2015 ////
//////////////////////////////////////////////////////////////////////
module simple_mac_top(
input clk,
input rst_n,
output mdc,
input mdio_in,
output mdio_out,
output mdio_oe,
output phy_rst_n,
input [7:0] rx_data,
output logic [7:0] tx_data,
input eth_mode,
input rx_clk,
input tx_clk,
input clk125out,
output tx_en,
input rx_data_valid,
input [7:0] reg_addr,
input reg_wr,
input [31:0] reg_wr_data,
input reg_rd,
output [31:0] reg_rd_data,
output reg_busy,
input ff_rx_clk,
output [31:0] ff_rx_data,
output ff_rx_eop,
output ff_rx_sop,
output rx_err,
output ff_rx_dval,
input ff_rx_rdy,
input ff_tx_clk,
input [31:0] 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 [7:0] rx_data_mac;
wire rx_data_valid_mac;
wire rx_sop_mac;
wire tx_data_valid_mac;
wire [7:0] tx_data_mac;
wire [31:0] ff_tx_data0;
wire ff_tx_eop0;
wire ff_tx_sop0;
wire ff_tx_wren0;
wire [31:0] 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 [47:0] 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 [15:0] 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[15:0]),
.reg_addr(reg_addr),
.wr(reg_wr),
.rd(reg_rd),
.data_out(mdio_rd_data),
.busy(mdio_busy)
);
wire [31:0] 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 |
|