ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

基于FPGA的ARP协议实现

2020-04-07 21:03:44  阅读:276  来源: 互联网

标签:ARP mii 基于 FPGA tx clk 地址 rst


一、ARP帧存在的作用:

       在网络通讯时,源主机的应用程序知道目的的IP地址和端口号,却不知道目的主机的硬件地址,而数据包首先是被网卡接收到再去处理上层协议的,如果接收到的数据包的硬件地址与本机不符,则直接丢弃。因此在通讯前必须获得目的主机的硬件地址。ARP协议就起这个作用。

 

二、ARP帧的工作原理:

       源主机发出ARP请求,询问“IP地址是 192.168.0.1的主机的硬件地址是多少”,并将这个请求广播到本地网段(以太网帧首部的硬件地址填 FF:FF:FF:FF:FF:FF表示广播),目的主机接收到广播的ARP请求,发现其中的IP地址与本机相符,则发送一个ARP应答数据包给源主机,将自己的硬件地址填写在应答包中。

 

三、ARP数据报格式

 

 ***  以太网目的地址:48'hff_ff_ff_ff_ff_ff,广播到电脑;

 ***  以太网源地址:48'h00_0a_35_01_fe_c0,开发板的以太网芯片地址(貌似是可以自己设定);

 ***  帧类型:0x0806表示ARP帧;

 *** 硬件类型:0x0001表示以太网类型值;

 *** 协议类型:0x0800表示上层协议为IP协议;

 *** 硬件地址长度:0x6表示以太网的地址长度是6个字节;

 *** 协议地址长度:0x4表示IP地址长度为4个字节;

 *** op:0x1表示ARP请求包,0x2表示ARP应答包;

 *** 发送者硬件地址:源MAC地址(开发板的以太网芯片地址);

 *** 发送者IP:发送方的IP地址;

 *** 目的硬件地址:电脑的MAC地址;

 *** 目标IP地址:电脑的IP地址;

 

四、MAC协议格式

 

  *** 前导码:55_55_55_55_55_55_55,是用来实现数据的同步;

  *** SFD:帧起始界定符:8'h5d,表示一帧的开始;

  *** FCS:为确保数据的正确传输,在数据的尾部加入了4个字节的循环冗余校验码(CRC校验) ;

 

五、ARP协议是加载在MAC协议上来发送的,如下图所示:

 

 

六、代码设计(参考的小梅哥的设计思路,在小梅哥的设计的基础上,做了小小的修改)

  1 // Time : 2020.04.06 21:12
  2 // Describe : eth_test 
  3 
  4 module eth_test(
  5       rst_n,
  6     
  7     //MII 接口信号    
  8     mii_tx_clk,
  9     mii_tx_en,
 10     mii_tx_er,
 11     mii_tx_data,
 12     
 13     mii_rx_clk,
 14     mii_rx_dv,
 15     mii_rx_er,
 16     mii_rx_data,
 17     
 18     phy_rst_n
 19 );
 20 
 21 input rst_n;
 22 
 23 input  mii_tx_clk;         //MII接口发送时钟,由PHY芯片产生,25MHz
 24 output mii_tx_en;           //MII接口发送数据使能信号,高电平有效
 25 output mii_tx_er;           //发送错误,用以破坏数据包发送
 26 output reg[3:0]mii_tx_data; //MII接口发送数据线,FPGA通过该数据线将需要发送的数据依次送给PHY芯片
 27 output phy_rst_n;           //PHY 复位信号
 28 
 29 input mii_rx_clk;           //MII接口接收时钟,由PHY芯片产生,25MHz
 30 input mii_rx_dv;           //MII接口接收数据有效信号,高电平有效
 31 input mii_rx_er;           //接收错误,本实例中暂时忽略该信号
 32 input [3:0]mii_rx_data;     //MII接口数据总线,FPGA通过该数据线读取PHY芯片接收到的以太网数据
 33 
 34 assign phy_rst_n = 1'b1;
 35 
 36 parameter des_mac     = 48'hff_ff_ff_ff_ff_ff;  //目标MAC地址
 37 parameter src_mac     = 48'h34_23_87_99_f4_61;  //本机/源MAC地址
 38 parameter type_length = 16'h08_06;                //数据帧类型
 39 parameter data_length = 12'd92;                   //数据长度(因为MII接口一个字节分两个时钟,每个时钟4位的方式发送,因此本值为实际数据所占字节数的2倍)
 40 
 41 parameter CRC = 32'h5b0ea9fa;                   //整个数据包CRC校验值,本例中使用CRC计算软件计算得出。
 42 
 43 wire[31:0] CRC_Result;
 44 
 45 assign CRC_Result = {CRC[7:0],CRC[15:8],CRC[23:16],CRC[31:24]};  //调整 CRC校验字字节顺序以符合以太网数据包校验格式
 46 
 47 wire tx_go;                // 使能发送
 48 
 49 reg [7:0] lsm_cnt;           //序列机计数器,本以太网帧发送系统使用线性序列机方式设计
 50 reg en_tx;                   //内部的数据帧发送使能信号,高电平时将数据通过MII接口送出
 51 
 52 reg [28:0]cnt;  //发送间隔计数器
 53 always@(posedge mii_tx_clk or negedge rst_n)
 54   if(!rst_n)
 55      cnt <= 28'd0;
 56   else if(cnt == 28'd3500)  // 35000000
 57      cnt <= 28'd0;
 58   else
 59     cnt <= cnt + 1'b1;
 60     
 61 //每671ms启动一次发送数据    
 62 assign tx_go = (cnt == 28'd3500) ? 1'b1 : 1'b0;  // 35000000
 63 
 64 //根据发送启动信号产生内部发送使能信号
 65 always@(posedge mii_tx_clk or negedge rst_n) 
 66   if(!rst_n)
 67      en_tx <= 1'd0;
 68   else if(tx_go)
 69      en_tx <= 1'd1;
 70   else if(lsm_cnt >= 145)      //一帧数据发送完成,清零发送使能信号
 71      en_tx <= 1'd0;
 72 
 73 always@(posedge mii_tx_clk or negedge rst_n) //主序列机计数器
 74   if(!rst_n)
 75      lsm_cnt <= 8'd0;
 76   else if(en_tx) begin
 77     if(lsm_cnt == 8'd145)
 78        lsm_cnt <= 8'd0;
 79      else
 80        lsm_cnt <= lsm_cnt + 1'b1;
 81   end
 82   else
 83      lsm_cnt <= 8'd0;    
 84      
 85 /*
 86 always@(posedge mii_tx_clk or negedge rst_n) 
 87   if(!rst_n) begin
 88     mii_tx_data <= 4'd0;
 89   end
 90   else begin
 91 */
 92 always@(*) begin
 93     case(lsm_cnt)
 94        1: mii_tx_data <= 4'h5;  // 前导码 + 分隔符的一个5
 95         2: mii_tx_data <= 4'h5;
 96         3: mii_tx_data <= 4'h5;
 97         4: mii_tx_data <= 4'h5;
 98         5: mii_tx_data <= 4'h5;
 99         6: mii_tx_data <= 4'h5;
100         7: mii_tx_data <= 4'h5;
101         8: mii_tx_data <= 4'h5;
102         9: mii_tx_data <= 4'h5;
103         10:mii_tx_data <= 4'h5;
104         11:mii_tx_data <= 4'h5;
105         12:mii_tx_data <= 4'h5;
106         13:mii_tx_data <= 4'h5;
107         14:mii_tx_data <= 4'h5;
108         15:mii_tx_data <= 4'h5;
109             
110         16: mii_tx_data <= 4'hd;  // 分隔符
111         
112       17: mii_tx_data <= des_mac[43:40];  // 目的MAC地址,先发高八位中的低四位 48'hff_ff_ff_ff_ff_ff
113         18: mii_tx_data <= des_mac[47:44];
114         19: mii_tx_data <= des_mac[35:32];
115         20: mii_tx_data <= des_mac[39:36];
116         21: mii_tx_data <= des_mac[27:24];
117         22: mii_tx_data <= des_mac[31:28];
118         23: mii_tx_data <= des_mac[19:16];
119         24: mii_tx_data <= des_mac[23:20];
120         25: mii_tx_data <= des_mac[11:8];
121         26: mii_tx_data <= des_mac[15:12];
122         27: mii_tx_data <= des_mac[3:0];
123         28: mii_tx_data <= des_mac[7:4];    
124     
125                   
126         29: mii_tx_data <= src_mac[43:40];// 0  //源MAC地址 48'h00_0a_35_01_fe_c0
127         30: mii_tx_data <= src_mac[47:44];// 0
128         31: mii_tx_data <= src_mac[35:32];// a
129         32: mii_tx_data <= src_mac[39:36];// 0
130         33: mii_tx_data <= src_mac[27:24];// 5
131         34: mii_tx_data <= src_mac[31:28];// 3
132         35: mii_tx_data <= src_mac[19:16];// 1
133         36: mii_tx_data <= src_mac[23:20];// 0
134         37: mii_tx_data <= src_mac[11:8]; // e
135         38: mii_tx_data <= src_mac[15:12];// f
136         39: mii_tx_data <= src_mac[3:0]; // 0
137         40: mii_tx_data <= src_mac[7:4];    // c
138         
139                     
140         41: mii_tx_data <= type_length[11:8];  //以太网帧类型/长度
141         42: mii_tx_data <= type_length[15:12];
142         43: mii_tx_data <= type_length[3:0];
143         44: mii_tx_data <= type_length[7:4];
144         
145         45: mii_tx_data =    4'h0;
146         46: mii_tx_data =    4'h0;
147         47: mii_tx_data =    4'h1;
148         48: mii_tx_data =    4'h0;
149         
150         //protocol type
151         49: mii_tx_data =    4'h8;
152         50: mii_tx_data =    4'h0;
153         51: mii_tx_data =    4'h0;
154         52: mii_tx_data =    4'h0;
155         
156         //hdwr size
157         53: mii_tx_data =    4'h6;
158         54: mii_tx_data =    4'h0;
159         
160         //protocol size
161         55: mii_tx_data =    4'h4;
162         56: mii_tx_data =    4'h0;
163         
164         //opcode
165         57: mii_tx_data =    4'h0;
166         58: mii_tx_data =    4'h0;
167         59: mii_tx_data =    4'h1;
168         60: mii_tx_data =    4'h0;
169         
170         //sender mac
171         61: mii_tx_data =    4'h0;
172         62: mii_tx_data =    4'h0;
173         63: mii_tx_data =    4'ha;
174         64: mii_tx_data =    4'h0;
175         65: mii_tx_data =    4'h5;
176         66: mii_tx_data =    4'h3;
177         67: mii_tx_data =    4'h1;
178         68: mii_tx_data =    4'h0;
179         69: mii_tx_data =    4'he;
180         70: mii_tx_data =    4'hf;
181         71: mii_tx_data =    4'h0;
182         72: mii_tx_data =    4'hc;
183         
184         //sender ip : 192.168.0.2
185         73: mii_tx_data =    4'h0;//192
186         74: mii_tx_data =    4'hc;
187         
188         75: mii_tx_data =    4'h8;//168
189         76: mii_tx_data =    4'ha;
190         
191         77: mii_tx_data =    4'h0;//0
192         78: mii_tx_data =    4'h0;
193         
194         79: mii_tx_data =    4'h2;
195         80: mii_tx_data =    4'h0;//2
196         
197         //target mac
198         81: mii_tx_data =    4'h4;  // 4  //48'b84 7b eb 48 94 13
199         82: mii_tx_data =    4'h3;  // 8  //48'b34 23 87 99 f4 61
200         83: mii_tx_data =    4'h3;  // b
201         84: mii_tx_data =    4'h2;  // 7
202         85: mii_tx_data =    4'h7;  // b
203         86: mii_tx_data =    4'h8;  // e
204         87: mii_tx_data =    4'h9;  // 8
205         88: mii_tx_data =    4'h9;  // 4
206         89: mii_tx_data =    4'h4;  // 4
207         90: mii_tx_data =    4'hf;  // 9
208         91: mii_tx_data =    4'h1;  // 3
209         92: mii_tx_data =    4'h6;  // 1
210         
211         //target ip : 192.168.0.3
212         93: mii_tx_data =    4'h0;//192
213         94: mii_tx_data =    4'hc;
214         
215         95: mii_tx_data =    4'h8;//168
216         96: mii_tx_data =    4'ha;
217         
218         97: mii_tx_data =    4'h0;//0
219         98: mii_tx_data =    4'h0;
220         
221         99: mii_tx_data =    4'h3;//3
222         100: mii_tx_data = 4'h0;
223         
224         //填充字段,以使整个数据帧长度达到64字节
225         101: mii_tx_data = 4'h0;
226         102: mii_tx_data = 4'h0;
227         103: mii_tx_data = 4'h0;
228         104: mii_tx_data = 4'h0;
229         105: mii_tx_data = 4'hf;
230         106: mii_tx_data = 4'hf;
231         107: mii_tx_data = 4'hf;
232         108: mii_tx_data = 4'hf;
233         109: mii_tx_data = 4'hf;
234         110: mii_tx_data = 4'hf;
235         111: mii_tx_data = 4'hf;
236         112: mii_tx_data = 4'hf;
237         113: mii_tx_data = 4'hf;
238         114: mii_tx_data = 4'hf;
239         115: mii_tx_data = 4'hf;
240         116: mii_tx_data = 4'hf;
241         117: mii_tx_data = 4'h0;
242         118: mii_tx_data = 4'h0;
243         119: mii_tx_data = 4'h3;
244         120: mii_tx_data = 4'h2;
245         121: mii_tx_data = 4'hd;
246         122: mii_tx_data = 4'hc;
247         123: mii_tx_data = 4'h6;
248         124: mii_tx_data = 4'h7;
249         125: mii_tx_data = 4'h3;
250         126: mii_tx_data = 4'h6;
251         127: mii_tx_data = 4'ha;
252         128: mii_tx_data = 4'h1;
253         129: mii_tx_data = 4'h8;
254         130: mii_tx_data = 4'h0;
255         131: mii_tx_data = 4'h6;
256         132: mii_tx_data = 4'h0;
257         133: mii_tx_data = 4'h0;
258         134: mii_tx_data = 4'h0;
259         135: mii_tx_data = 4'h1;
260         136: mii_tx_data = 4'h0;
261         
262         137: mii_tx_data <= CRC_Result[27:24];  //发送CRC 校验结果
263         138: mii_tx_data <= CRC_Result[31:28];
264         139: mii_tx_data <= CRC_Result[19:16];
265         140: mii_tx_data <= CRC_Result[23:20];
266         141: mii_tx_data <= CRC_Result[11:8];
267         142: mii_tx_data <= CRC_Result[15:12];
268         143: mii_tx_data <= CRC_Result[3:0];
269         144: mii_tx_data <= CRC_Result[7:4];
270 
271         145: mii_tx_data <= 4'd0;
272         default: mii_tx_data <= 4'd0;
273      endcase
274   end
275   
276 /*
277 always@(posedge mii_tx_clk or negedge rst_n)  //MII数据发送使能信号
278   if(!rst_n)
279      mii_tx_en <= 1'b0;
280   else if((lsm_cnt >= 1) && (lsm_cnt <= 144))  // lsm_cnt >= 1
281      mii_tx_en <= 1'b1;
282   else
283      mii_tx_en <= 1'b0;
284 */
285 
286 assign mii_tx_en = ((lsm_cnt >= 1) && (lsm_cnt <= 144)) ? 1'b1 : 1'b0;
287 
288 endmodule
289     
View Code

测试代码:

 1 `timescale 1ns/1ns
 2 
 3 module eth_test_tb;
 4 
 5     reg rst_n;    
 6     //MII 接口信号    
 7     reg mii_tx_clk;
 8     wire mii_tx_en;
 9     wire mii_tx_er;
10     wire [3:0]mii_tx_data;
11     wire phy_rst_n;
12 
13     eth_test eth_test(
14         .rst_n(rst_n),
15         .mii_tx_clk(mii_tx_clk),
16         .mii_tx_en(mii_tx_en),
17         .mii_tx_er(mii_tx_er),
18         .mii_tx_data(mii_tx_data),
19         .phy_rst_n(phy_rst_n)
20     );
21     
22     initial mii_tx_clk = 1;
23     always #20 mii_tx_clk = ~mii_tx_clk;
24     
25     initial begin
26         rst_n = 0;
27         #201;
28         rst_n = 1;
29         
30         #1000000;
31       
32         $stop;
33     end
34 
35 endmodule
View Code

仿真效果:

 

 图1

 

 

 图2

上板效果图:

 

 图3

注:代码设计参考了小梅哥的设计,梅哥写的比较简单易懂,文字叙述方面也摘抄了梅哥的《基于ac620的fpga系统设计与验证实战指南20190516》;

 

标签:ARP,mii,基于,FPGA,tx,clk,地址,rst
来源: https://www.cnblogs.com/571328401-/p/12655923.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有