已经在昨天下午实验通过UDP包传输给PC。
使用的是一块ALTERA的板子,芯片是RTL8211EG:
上图用的是一块我自己设计的开发板的一个打样板。
上图是设置PC电脑的连接网口IP为.11,咱们FPGA板的IP地址是.22 .
实现的大体过程如下:
我们再回顾一下一个UDP包从FPGA板子发到电脑的过程。
1,UDP发送请求到IP层,IP层传递到MAC管理层。
2,MAC管理层从ARP_CACHE里面找IP对应的UDP,没有找到进入3,如果找到进入X
3,设置ARP_GEN模块发送出去一个ARP_REQUEST数据包。
4,PC收到后响应发出ARP_REPLY给到FPGA板。
5,FPGA板子收到后更新ARP_CACHE加入IP和MAC的对应。
6,MAC管理层下次轮询到要发送的IP包的时候,从ARP_CACHE里找到了对应的MAC地址。
7,设置IP和MAC地址给MAC发送模块发出此载有UDP数据包的IP包。
在之前做仿真的时候我们写好了可以实现上述实验的udp_top模块,这里我们我们再写一个自动发送模块:
module auto_sending (
input clk ,rst ,
output tx_en,
output [7:0] tx_dout,
input rx_dv,
input [7:0] rx_din ,
input tx_clk,rx_clk
);
wire [31:0]my_a_ip ={8'd192,8'd168,8'd3,8'h22} ;
wire [47:0]my_a_mac =48'HA1A2A3A4A5A6;
wire [31:0]my_a_udp_port = 'h8080;
wire [31:0]my_b_ip ={8'd192,8'd168,8'd3,8'd11} ;
//wire [47:0]my_b_mac =48'hB1B2B3B4B5B6;
wire [31:0]my_b_udp_port = 'h8080 ;
wire [15:0] test_len = 16'd32;
//wire [15:0] test_len = 1440;
reg [11:0] c;always @(posedge clk) if (rst) c<=0; else c<=(c==(1000-1))?0:c+1; // system counter for debug
reg [7:0] st = 0 ;
reg [15:0] r;
reg [31:0]d ;always @ ( posedge clk ) if (st==5)d<=d+1;else d<=0;
always @ ( posedge clk ) if (rst)st<=0; else case (st)
0:st<=5;
5: if (d == 1000*1000*125*5 ) st<=100;//send every 1 second
//5:st<=10;
10:if(s_udp_tx_busy==0)st<=20;
20:st<=30;
30:if(r==test_len)st<=40;
40:st<=5;
default st<=0;
endcase
reg s_udp_tx_start=0;
always @(posedge clk) if (rst){s_udp_tx_start,r}<=0; else case (st)
20:begin r<=0;s_udp_tx_start <=1; end
30:begin r<=r+1; s_udp_tx_start <=0; end
default begin r<=0;s_udp_tx_start <=0;end
endcase
wire [7:0] a2b_u8 ,b2a_u8 ;
wire a2b_en,b2a_en;
wire [7:0] tx_dout_int,rx_din_int;
wire tx_en_int,rx_dv_int ;
udp_top a(
.clk (clk),
.rst(rst) ,
.s_udp_dst_ip(my_b_ip),
.s_udp_src_port(my_a_udp_port),
.s_udp_dst_port (my_b_udp_port),
.s_udp_tx_busy(s_udp_tx_busy),
.s_udp_tx_len(test_len),
.s_udp_tx_dat(r[7:0]),
.s_udp_ip_id('hb3fe),
.s_udp_tx_start(s_udp_tx_start),
.phy_tx_dout( tx_dout_int ) ,
.phy_tx_err(),
.phy_tx_en( tx_en_int ),
.phy_rx_din(rx_din_int ),
.phy_rx_dv(rx_dv_int ),
.cfg_my_ip(my_a_ip),
.cfg_my_mac(my_a_mac)
);
// cdc_fifo cdc_fifo_fpga2phy ( .wr_clk( clk ), .rst(rst ),.wr_en( tx_en_int) ,.wr_dat( tx_dout_int),.rd_clk(tx_clk ),.rd_dat(tx_dout ),.rd_vd( tx_en) );
assign { tx_dout,tx_en} = {tx_dout_int ,tx_en_int};
cdc_fifo cdc_fifo_phy2fpga ( .wr_clk( rx_clk ),.rst(rst ),.wr_en( rx_dv) ,.wr_dat( rx_din ),.rd_clk(clk ),.rd_dat(rx_din_int ),.rd_vd( rx_dv_int) );
这里就是设置每5秒钟发送一个载有32字节报文的UDP包给电脑,UDP段收到后解析。我们看到这里没有任何ARP的设置,物理地址(MAC地址)请求是自动进行的。
这里看到我们的发送信息:
wire [31:0]my_a_ip ={8'd192,8'd168,8'd3,8'h22} ;
wire [47:0]my_a_mac =48'HA1A2A3A4A5A6;
wire [31:0]my_a_udp_port = 'h8080;
上述是FPGA板子的MAC地址,IP地址,以及端口号。
wire [31:0]my_b_ip ={8'd192,8'd168,8'd3,8'd11} ;
///wire [47:0]my_b_mac =48'hB1B2B3B4B5B6;
wire [31:0]my_b_udp_port = 'h8080 ;
上述是与之连通的PC机IP地址和UDP端口号。
上图是层次在QUARTUS下的层次结构。