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

图1 top.v模块
代码如下:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 |
`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四个模块。其代码如下:

图2 ETH_CORE.v模块
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 |
`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,提高模块的通用性。