Menu Close

网络综合实验 Verilog工程(top.v及ETH_CORE.v)

top.v 是整个网络综合实验工程的顶层模块,如图1所示。在这个模块里例化了PLL时钟模块IP核,和网络综合实验的核心模块ETH_CORE.v。

%title插图%num

图1 top.v模块

代码如下:

`timescale 1ns / 1ps


module top #
(
    parameter MAC_TX_CRC_EN             = 1, // 0: MAC DON'T CALC CRC; 1: MAC CALC CRC

    parameter [47:0] TX_MAC_SRC         = 48'h46_72_61_73_65_72,
    parameter [47:0] TX_MAC_DES         = 48'hff_ff_ff_ff_ff_ff,

    parameter [31:0] TX_IP_SRC          = 32'hc0a8003d,
    parameter [31:0] TX_IP_DES          = 32'hc0a800a8,
    parameter [15:0] UDP_TX_SRC_PORT    = 10000,
    parameter [15:0] UDP_TX_DES_PORT    = 10000,
    parameter UDP_TX_CHECKSUM_EN        = 1, // 0: UDP checksum = 16'h0000; 1: calc checksum
    

    parameter [31:0] RX_IP_SRC          = 32'hc0a800a8,
    parameter RX_IP_SRC_EN              = 1, // 0: don't check src ip address; 1: check src ip address
    parameter [31:0] RX_IP_DES          = 32'hc0a8003d,
    parameter RX_IP_DES_EN              = 1, // 0: don't check des ip address; 1: check des ip address

    parameter [15:0] UDP_RX_SRC_PORT    = 10000,
    parameter UDP_RX_SRC_PORT_EN        = 1, // 0: don't check udp src port; 1: check udp src port
    parameter [15:0] UDP_RX_DES_PORT    = 10000,
    parameter UDP_RX_DES_PORT_EN        = 1, // 0: don't check udp des port; 1: check udp des port
    
    parameter MAIN_CLK                  = 125,
    parameter PHY_SPEED                 = "AUTO"  // "AUTO", "1G", "100M", "10M"
)
(

    input        OSC_CLK,
    
    output       E_MDC,
    inout        E_MDIO,

    input        E_RXC,
    input        E_RXDV,
    input  [3:0] E_RXD,

    output       E_TXC,         //以太网发送时钟
    output       E_TXEN,        //发送使能
    output [3:0] E_TXD,         //发送数据

    output       ETH_RSTN,
    input        ETH_IRQ,
    
//    input  [7:0] SW,
    output [7:0] LED            //发送指示灯
);
    
//=========================================================================
//时钟模块
wire locked;
wire clk_200m;
wire clk_125m;
wire clk_125m_90;

MMCM SYS_DCM_inst
(
    // Clock in ports
    .clk_in1    (OSC_CLK),
    // Clock out ports
    .clk_out1   (clk_200m),     // 200M
    .clk_out2   (clk_125m),     // 125M
    .clk_out3   (clk_125m_90),  // 125M

    // Status and control signals
    .reset      (1'b0),     // input reset
    .locked     (locked)    // output locked
);
wire    sys_clk = clk_125m;
wire    ref_clk = clk_200m;

reg locked_r = 0;
always @ (posedge sys_clk)
locked_r <= locked;

reg [7:0] lock_cnt = 0;
reg reset = 1;
always @ (posedge sys_clk)
if(!locked_r) 
begin
    lock_cnt <= 0;
    reset <= 1;
end
else
begin
    if(&lock_cnt)  reset <= 0;
    else lock_cnt <= lock_cnt + 1;
end


wire    sys_rst_n  = ~reset;
//=========================================================================

wire	   e_mdio_i;
wire       e_mdio_o;
wire       e_mdio_t;

IOBUF #(
    .SLEW("SLOW") // Specify the output slew rate
) mdio_inst (
    .O  (e_mdio_i),     // Buffer output
    .IO (E_MDIO),       // Buffer inout port (connect directly to top-level port)
    .I  (e_mdio_o),     // Buffer input
    .T  (e_mdio_t)      // 3-state enable input, high=input, low=output
);

wire [7:0] udp_dout;
wire       udp_dout_en;

wire [7:0] udp_din = udp_dout;
wire       udp_din_vld = udp_dout_en;

wire [2:0] eth_speed;

ETH_CORE   #
(   
// TX
    .MAC_TX_CRC_EN      (MAC_TX_CRC_EN),
    .TX_MAC_SRC         (TX_MAC_SRC),
    .TX_MAC_DES         (TX_MAC_DES),

    .TX_IP_SRC          (TX_IP_SRC),
    .TX_IP_DES          (TX_IP_DES),
    .UDP_TX_SRC_PORT    (UDP_TX_SRC_PORT),
    .UDP_TX_DES_PORT    (UDP_TX_DES_PORT),
    .UDP_TX_CHECKSUM_EN (UDP_TX_CHECKSUM_EN),
// RX    
    .RX_IP_SRC          (RX_IP_SRC),
    .RX_IP_SRC_EN       (RX_IP_SRC_EN),
    .RX_IP_DES          (RX_IP_DES),
    .RX_IP_DES_EN       (RX_IP_DES_EN),
    
    .UDP_RX_SRC_PORT    (UDP_RX_SRC_PORT),
    .UDP_RX_SRC_PORT_EN (UDP_RX_SRC_PORT_EN),
    .UDP_RX_DES_PORT    (UDP_RX_DES_PORT),
    .UDP_RX_DES_PORT_EN (UDP_RX_DES_PORT_EN),

    .MAIN_CLK           (MAIN_CLK), // 125m sys_clk
    .PHY_SPEED          (PHY_SPEED) // "AUTO", "1G", "100M", "10M"
)
ETH_CORE_inst
(
    .ref_clk    (ref_clk),

    .E_RXC      (E_RXC),
    .E_RXDV     (E_RXDV),
    .E_RXD      (E_RXD),

    .E_TXC      (E_TXC),         //以太网发送时钟
    .E_TXEN     (E_TXEN),        //发送使能
    .E_TXD      (E_TXD),         //发送数据

// sys clk
    .sys_clk    (sys_clk),
    .e_mdc      (E_MDC),
    .e_mdio_i   (e_mdio_i),
    .e_mdio_o   (e_mdio_o),
    .e_mdio_t   (e_mdio_t),

    .eth_speed  (eth_speed),

    .udp_din    (udp_din),
    .udp_din_vld(udp_din_vld),
    .udp_din_rdy(udp_din_rdy),
    
    
    .udp_dout   (udp_dout),
    .udp_dout_en(udp_dout_en),
    
    .reset      (reset)
);


reg [31:0] led_cnt;
always @ (posedge sys_clk or posedge reset)
if(reset)   led_cnt <= 0;
else        led_cnt <= led_cnt + 1;

reg [2:0] eth_speed_r = 0;
always @ (posedge sys_clk or posedge reset)
if(reset)   eth_speed_r <= 0;
else        eth_speed_r <= ~eth_speed;

    
assign LED[0] = 1;
assign LED[1] = led_cnt[25];
assign LED[4:2] = 3'b111;
assign LED[7:5] = eth_speed_r;


assign ETH_RSTN = 1'b1;
//=========================================================================
endmodule

 

注意从top.v传递了很多参数到下层模块:

parameter MAC_TX_CRC_EN = 1,             // 0: MAC DON’T CALC CRC; 1: MAC CALC CRC

parameter [47:0] TX_MAC_SRC = 48’h46_72_61_73_65_73,     //源MAC地址
parameter [47:0] TX_MAC_DES = 48’hff_ff_ff_ff_ff_ff,               //目的MAC地址

//发送相关参数

parameter [31:0] TX_IP_SRC = 32’hc0a8003e,                                //源IP地址(这里指FPGA)
parameter [31:0] TX_IP_DES = 32’hc0a8002e,                                //目的IP地址(这里指主机)
parameter [15:0] UDP_TX_SRC_PORT = 10000,                            //源端口(这里指FPGA)
parameter [15:0] UDP_TX_DES_PORT = 10000,                           //目的端口(这里指主机)
parameter UDP_TX_CHECKSUM_EN = 1,             // 0: UDP checksum = 16’h0000; 1: calc checksum

//接收相关参数

parameter [31:0] RX_IP_SRC = 32’hc0a8002e,                             //源IP地址(这里指主机)
parameter RX_IP_SRC_EN = 1,                     // 0: don’t check src ip address; 1: check src ip address
parameter [31:0] RX_IP_DES = 32’hc0a8003e,                              //目的IP地址(这里指FPGA)
parameter RX_IP_DES_EN = 1,                    // 0: don’t check des ip address; 1: check des ip address

parameter [15:0] UDP_RX_SRC_PORT = 10000,                          //源端口(这里指主机)
parameter UDP_RX_SRC_PORT_EN = 1,                // 0: don’t check udp src port; 1: check udp src port
parameter [15:0] UDP_RX_DES_PORT = 10000,                            //目的端口(这里指FPGA)
parameter UDP_RX_DES_PORT_EN = 1,                // 0: don’t check udp des port; 1: check udp des port

parameter MAIN_CLK = 125,                                       //时钟主频,单位是MHz
parameter PHY_SPEED = “AUTO”                  // “AUTO”, “1G”, “100M”, “10M”

 

ETH_CORE.v是网络综合实验的核心模块,如图2所示。例化了ETH_UDP.v,ETH_IP.v,ETH_MAC.v 和eth_phy_core.v四个模块。其代码如下:

%title插图%num

图2 ETH_CORE.v模块

`timescale 1ns / 1ps


module ETH_CORE #
(
// TX
    parameter MAC_TX_CRC_EN             = 1,

    parameter [47:0] TX_MAC_SRC         = 48'h66_72_61_73_65_72,
    parameter [47:0] TX_MAC_DES         = 48'hff_ff_ff_ff_ff_ff,

    parameter [31:0] TX_IP_SRC          = 32'hc0a8003d,
    parameter [31:0] TX_IP_DES          = 32'hc0a800ff,
    parameter [15:0] UDP_TX_SRC_PORT    = 16'hffff,
    parameter [15:0] UDP_TX_DES_PORT    = 16'hffff,
    parameter UDP_TX_CHECKSUM_EN        = 0,
    
// RX
    parameter [31:0] RX_IP_SRC          = 32'hc0a8003d,
    parameter RX_IP_SRC_EN              = 0,
    parameter [31:0] RX_IP_DES          = 32'hc0a800ff,
    parameter RX_IP_DES_EN              = 0,

    parameter [15:0] UDP_RX_SRC_PORT    = 16'hffff,
    parameter UDP_RX_SRC_PORT_EN        = 0,
    parameter [15:0] UDP_RX_DES_PORT    = 16'hffff,
    parameter UDP_RX_DES_PORT_EN        = 0,
    
    parameter MAIN_CLK                  = 125,
    parameter PHY_SPEED                 = "AUTO"  // "AUTO", "1G", "100M", "10M"
)
(
    input        ref_clk,
    
    input        E_RXC,
    input        E_RXDV,
    input  [3:0] E_RXD,

    output       E_TXC,         //以太网发送时钟
    output       E_TXEN,        //发送使能
    output [3:0] E_TXD,         //发送数据

    input        sys_clk,
    
    output       e_mdc,
    input	     e_mdio_i,
    output       e_mdio_o,
    output       e_mdio_t,
    
    output [2:0] eth_speed,

    input  [7:0] udp_din,
    input        udp_din_vld,
    output       udp_din_rdy,
    
(* mark_debug = "true" *)    output [7:0] udp_dout,
(* mark_debug = "true" *)    output       udp_dout_en,
    
    input        reset
);
//=========================================================================
localparam IP_BUF_SIZE = 10;
localparam IP_IDX_BIT  = 1;
//=========================================================================
wire  udp_tx_wea;
wire [IP_BUF_SIZE + IP_IDX_BIT - 1:0] udp_tx_addra;
wire  [15:0] udp_tx_dina;
wire  [15:0] udp_tx_douta;


wire  udp_rx_web;
wire  [IP_BUF_SIZE + IP_IDX_BIT - 1:0] udp_rx_addrb;
wire  [15:0] udp_rx_doutb;

(* mark_debug = "true" *)wire [4:0] udp_error;
ETH_UDP #
(
    .TX_IP_SRC          (TX_IP_SRC),
    .TX_IP_DES          (TX_IP_DES),
    .UDP_TX_SRC_PORT    (UDP_TX_SRC_PORT),
    .UDP_TX_DES_PORT    (UDP_TX_DES_PORT),
    .UDP_TX_CHECKSUM_EN (UDP_TX_CHECKSUM_EN),
    
    .UDP_RX_SRC_PORT    (UDP_RX_SRC_PORT),
    .UDP_RX_SRC_PORT_EN (UDP_RX_SRC_PORT_EN),
    .UDP_RX_DES_PORT    (UDP_RX_DES_PORT),
    .UDP_RX_DES_PORT_EN (UDP_RX_DES_PORT_EN),
    
    .IP_BUF_SIZE        (IP_BUF_SIZE),
    .IP_IDX_BIT         (IP_IDX_BIT)
)
ETH_UDP_inst
(
    .sys_clk        (sys_clk),
// tx
    .udp_din        (udp_din),
    .udp_din_vld    (udp_din_vld),
    .udp_din_rdy    (udp_din_rdy),
    
    .udp_tx_wea     (udp_tx_wea),
    .udp_tx_addra   (udp_tx_addra),
    .udp_tx_dina    (udp_tx_dina),
    .udp_tx_douta   (udp_tx_douta),
// rx
    .udp_rx_web     (udp_rx_web),
    .udp_rx_addrb   (udp_rx_addrb),
    .udp_rx_doutb   (udp_rx_doutb),

    .udp_dout       (udp_dout),
    .udp_dout_en    (udp_dout_en),
    
    .udp_error      (udp_error),
    .reset          (reset)
);

//=========================================================================
localparam MAC_TXBUF_SIZE = IP_BUF_SIZE + 1;
localparam MAC_TXIDX_BIT  = IP_IDX_BIT;
//=========================================================================
wire  [17:0] ip_fifo_din;
wire         ip_fifo_we;
wire  [15:0] ip_fifo_cnt;

wire  ip_rx_web;
wire  [IP_BUF_SIZE + IP_IDX_BIT - 1:0] ip_rx_addrb;
wire  [15:0] ip_rx_doutb;

(* mark_debug = "true" *)wire [7:0] rx_ip_err;

ETH_IP #
(
    .TX_MAC_SRC     (TX_MAC_SRC),
    .TX_MAC_DES     (TX_MAC_DES),

    .TX_IP_SRC      (TX_IP_SRC),
    .TX_IP_DES      (TX_IP_DES),

    .RX_IP_SRC      (RX_IP_SRC),
    .RX_IP_SRC_EN   (RX_IP_SRC_EN),
    .RX_IP_DES      (RX_IP_DES),
    .RX_IP_DES_EN   (RX_IP_DES_EN),
    
    .IP_BUF_SIZE    (IP_BUF_SIZE),
    .IP_IDX_BIT     (IP_IDX_BIT)
)
ETH_IP_inst
(
    .sys_clk        (sys_clk),

    .udp_tx_wea     (udp_tx_wea),
    .udp_tx_addra   (udp_tx_addra),
    .udp_tx_dina    (udp_tx_dina),
    .udp_tx_douta   (udp_tx_douta),

    .ip_fifo_din    (ip_fifo_din),
    .ip_fifo_we     (ip_fifo_we),
    .ip_fifo_cnt    (ip_fifo_cnt),
// =================================
    .udp_rx_web     (udp_rx_web),
    .udp_rx_addrb   (udp_rx_addrb),
    .udp_rx_doutb   (udp_rx_doutb),

    .ip_rx_web      (ip_rx_web),
    .ip_rx_addrb    (ip_rx_addrb),
    .ip_rx_doutb    (ip_rx_doutb),
    
    .rx_ip_err      (rx_ip_err),
// =================================
    
    .reset          (reset)
);
//=========================================================================
wire       phy_rx_clk;
(* mark_debug = "true" *)wire [7:0] phy_rx_data;
(* mark_debug = "true" *)wire       phy_rx_toggle;
(* mark_debug = "true" *)wire       phy_rx_dv;

wire       phy_tx_clk = phy_rx_clk;
(* mark_debug = "true" *)wire [7:0] phy_tx_data;
(* mark_debug = "true" *)wire [1:0] phy_tx_en;

(* mark_debug = "true" *)wire [7:0] mac_error;
wire       smi_done;
ETH_MAC   #
(   
    .MAC_TX_CRC_EN  (MAC_TX_CRC_EN),
    
    .IP_BUF_SIZE    (IP_BUF_SIZE),
    .IP_IDX_BIT     (IP_IDX_BIT),
    
    .MAC_TXBUF_SIZE (MAC_TXBUF_SIZE),
    .MAC_TXIDX_BIT  (MAC_TXIDX_BIT)
)
ETH_MAC_inst
(
    .sys_clk        (sys_clk),
// tx
    .ip_fifo_din    (ip_fifo_din),
    .ip_fifo_we     (ip_fifo_we),
    .ip_fifo_cnt    (ip_fifo_cnt),
// rx    
    .ip_rx_web      (ip_rx_web),
    .ip_rx_addrb    (ip_rx_addrb),
    .ip_rx_doutb    (ip_rx_doutb),
    
    .mac_error      (mac_error),
// =================================
    .phy_rx_clk     (phy_rx_clk),
    .phy_rx_data    (phy_rx_data),
    .phy_rx_toggle  (phy_rx_toggle),
    .phy_rx_dv      (phy_rx_dv),

    .phy_tx_clk     (phy_tx_clk),
    .phy_tx_data    (phy_tx_data),
    .phy_tx_en      (phy_tx_en),

    .smi_done       (smi_done),
    .eth_speed      (eth_speed),
// =================================
    .reset          (reset)
);
//=========================================================================
eth_phy_core #
(
    .MAIN_CLK   (MAIN_CLK),
    .PHY_SPEED  (PHY_SPEED)
)
eth_phy_core_inst
(
    .ref_clk        (ref_clk),

    .E_RXC          (E_RXC),
    .E_RXDV         (E_RXDV),
    .E_RXD          (E_RXD),

    .E_TXC          (E_TXC),         //以太网发送时钟
    .E_TXEN         (E_TXEN),        //发送使能
    .E_TXD          (E_TXD),         //发送数据

    .sys_clk        (sys_clk),
    .smi_done       (smi_done),
    .e_mdc          (e_mdc),
    .e_mdio_i       (e_mdio_i),
    .e_mdio_o       (e_mdio_o),
    .e_mdio_t       (e_mdio_t),

    .eth_speed      (eth_speed),

    .phy_rx_clk     (phy_rx_clk),
    .phy_rx_dv      (phy_rx_dv),
    .phy_rx_data    (phy_rx_data),
    .phy_rx_toggle  (phy_rx_toggle),

    .phy_tx_clk     (phy_tx_clk),
    .phy_tx_data    (phy_tx_data),
    .phy_tx_en      (phy_tx_en),
    
    .reset          (reset)
);

//=========================================================================
    
endmodule

 

 

在ETH_CORE.v模块中也有一些参数传递给下层的子模块,如下所示:

localparam IP_BUF_SIZE = 10;
localparam IP_IDX_BIT = 1;

localparam MAC_TXBUF_SIZE = IP_BUF_SIZE + 1;
localparam MAC_TXIDX_BIT = IP_IDX_BIT;

这些参数主要用来参数化IP和MAC层使用的A/B Buffer和FIFO,提高模块的通用性。

 

Posted in FPGA, FPGA 教材教案, Verilog, Verilog, Vivado, Vivado, 开发工具, 开发工具, 开发语言, 教材与教案, 文章, 编程语言

1 Comment

发表回复

相关链接