实验报告 · 本节笔记
课程:中级 | FPGA工程师实战精进课程(送板卡+证书) · 第一部分 进阶接口设计篇
发布自课程云笔记 · FPGA 实验证据骨架
【本节要点】
mac层:
ARP包:
28字节 ARP协议(请求或应答):
组装后的ARP请求包:
【疑问/坑点】
【可复用的代 码/思路】
ARP_TX端代码
`timescale 1ns / 1ps
module ARP_TX(
input wire arp_txc ,//时钟
input wire rst_n ,//复位
input wire arp_tx_en ,//arp发送使能信号
input wire arp_tx_op ,//arp发送数据包的类型:请求|应答
input wire [47:0] des_mac ,//接收到请求包(源mac),发送应答包(目的mac)
input wire [31:0] des_ip ,//接收到请求包
output reg [7:0] arp_txd ,//数据
output reg arp_txv ,//有效信号
output wire arp_tx_done ,//结束信号
input wire [31:0] crc_d ,//crc32校验数据
output reg crc_e ,//开始校验的使能
output reg crc_init //初始化信号
);
parameter FPGA_MAC = 48'h00_11_22_33_44_55 ;
parameter FPGA_IP = 32'hC0_A8_00_03 ;
parameter PC_MAC = 48'hFF_FF_FF_FF_FF_FF ;//以广播的形式发送请求包
parameter PC_IP = 32'hC0_A8_00_11 ;
localparam IDLE = 1 ,//空闲
PREAMBL = 2 ,//前导码 6字节 0~6
SFD = 3 ,//帧起始界定符 1字节 6~7
ETH_MAC0 = 4 ,//目的PC MAC 6字节 8~13
ETH_MAC_S = 5 ,//源FPGA MAC 6字节 14~19
ARP_START0 = 6 ,//长度|类型 2字节 20~21
ARP_START1 = 7 ,//硬件类型 2字节 22~23
ARP_START2 = 8 ,//协议类型 2字节 24~25
ARP_START3 = 9 ,//硬件地址长度6 1字节 26
ARP_START4 = 10 ,//协议地址长度6 1字节 27
OP = 11 ,//arp协议类型 2字节 28~29
ETH_MAC_S1 = 12 ,//源FPGA MAC 6字节 30~35
ETH_IP_S1 = 13 ,//源FPGA IP 4字节 36~39
ETH_MAC1 = 14 ,//目的MAC PC 6字节 40~45
ETH_IP1 = 15 ,//目的IP PC 4字节 46~49
ARP_START5 = 16 ,//18字节00占位 18字节 50~67
CRC = 17 ;//CRC32校验 4字节 68~71
reg [4:0] cur_s ;//现态
reg [4:0] nex_s ;//次态
reg [6:0] cnt_byte ;//字节计数
always @(posedge arp_txc)
begin
if(!rst_n)
cur_s <= IDLE ;
else
cur_s <= nex_s ;
end
always @(*)
begin
case (cur_s)
IDLE :
begin
if(arp_tx_en)
nex_s = PREAMBL ;
else
nex_s = cur_s ;
end
PREAMBL :
begin
if(cnt_byte == 6)
nex_s = SFD ;
else
nex_s = cur_s ;
end
SFD :
begin//nex_s = ETH_MAC0 ; //只有一个字节也可以直接跳变到下个状态
if(cnt_byte == 7)
nex_s = ETH_MAC0 ;
else
nex_s = cur_s ;
end
ETH_MAC0 :
begin
if(cnt_byte == 13)//8~13
nex_s = ETH_MAC_S ;
else
nex_s = cur_s ;
end
ETH_MAC_S :
begin
if(cnt_byte == 19)//14~19
nex_s = ARP_START0 ;
else
nex_s = cur_s ;
end
ARP_START0 :
begin
if(cnt_byte == 21)//20~21
nex_s = ARP_START1 ;
else
nex_s = cur_s ;
end
ARP_START1 :
begin
if(cnt_byte == 23)//22~23
nex_s = ARP_START2 ;
else
nex_s = cur_s ;
end
ARP_START2 :
begin
if(cnt_byte == 25)//24~25
nex_s = ARP_START3 ;
else
nex_s = cur_s ;
end
ARP_START3 :
begin//nex_s = ARP_START4 ;//只有一个字节也可以直接跳变到下个状态
if(cnt_byte == 26)
nex_s = ARP_START4 ;
else
nex_s = cur_s ;
end
ARP_START4 :
begin//nex_s = OP ;//只有一个字节也可以直接跳变到下个状态
if(cnt_byte == 27)
nex_s = OP ;
else
nex_s = cur_s ;
end
OP :
begin
if(cnt_byte == 29)//28~29
nex_s = ETH_MAC_S1 ;
else
nex_s = cur_s ;
end
ETH_MAC_S1 :
begin
if(cnt_byte == 35)//30~35
nex_s = ETH_IP_S1 ;
else
nex_s = cur_s ;
end
ETH_IP_S1 :
begin
if(cnt_byte == 39)//36~39
nex_s = ETH_MAC1 ;
else
nex_s = cur_s ;
end
ETH_MAC1 :
begin
if(cnt_byte == 45)//40~45
nex_s = ETH_IP1 ;
else
nex_s = cur_s ;
end
ETH_IP1 :
begin
if(cnt_byte == 49)//46~49
nex_s = ARP_START5 ;
else
nex_s = cur_s ;
end
ARP_START5 :
begin
if(cnt_byte == 67)//50~67
nex_s = CRC ;
else
nex_s = cur_s ;
end
CRC :
begin
if(cnt_byte == 71)//68~71
nex_s = IDLE ;
else
nex_s = cur_s ;
end
default : nex_s = IDLE ;
endcase
end
//字节计数器
always @(posedge arp_txc)
begin
if(!rst_n)
cnt_byte <= 0 ;
else if(cur_s == IDLE)
cnt_byte <= 0 ;
else
cnt_byte <= cnt_byte + 1 ;
end
always @(posedge arp_txc)
begin
if(!rst_n)
arp_txd <= 0 ;
else
case (cur_s)
IDLE : arp_txd <= 0 ;
PREAMBL : arp_txd <= 8'h55 ;
SFD : arp_txd <= 8'hd5 ;
ETH_MAC0 :
begin
if(arp_tx_op)
arp_txd <= 8'hff ;
else
begin
case (cnt_byte)
8 :arp_txd <= des_mac[47:40] ;
9 :arp_txd <= des_mac[39:32] ;
10 :arp_txd <= des_mac[31:24] ;
11 :arp_txd <= des_mac[23:16] ;
12 :arp_txd <= des_mac[15:8] ;
13 :arp_txd <= des_mac[7:0] ;
default :arp_txd <= des_mac[47:40] ;
endcase
end
end
ETH_MAC_S :
begin
case (cnt_byte)
14 :arp_txd <= FPGA_MAC[47:40] ;
15 :arp_txd <= FPGA_MAC[39:32] ;
16 :arp_txd <= FPGA_MAC[31:24] ;
17 :arp_txd <= FPGA_MAC[23:16] ;
18 :arp_txd <= FPGA_MAC[15:8] ;
19 :arp_txd <= FPGA_MAC[7:0] ;
default :arp_txd <= FPGA_MAC[47:40] ;
endcase
end
ARP_START0 :
begin
case (cnt_byte)
20 :arp_txd <= 8'h08 ;
21 :arp_txd <= 8'h06 ;
default :arp_txd <= 8'h08 ;
endcase
end
ARP_START1 :
begin
case (cnt_byte)
22 :arp_txd <= 8'h00 ;
23 :arp_txd <= 8'h01 ;
default :arp_txd <= 8'h00 ;
endcase
end
ARP_START2 :
begin
case (cnt_byte)
24 :arp_txd <= 8'h08 ;
25 :arp_txd <= 8'h00 ;
default :arp_txd <= 8'h08 ;
endcase
end
ARP_START3 : arp_txd <= 8'h06 ;
ARP_START4 : arp_txd <= 8'h04 ;
OP :
begin
if(arp_tx_op)
begin
case (cnt_byte)
28 :arp_txd <= 8'h00 ;
29 :arp_txd <= 8'h01 ;
default :arp_txd <= 8'h00 ;
endcase
end
else
begin
case (cnt_byte)
28 :arp_txd <= 8'h00 ;
29 :arp_txd <= 8'h02 ;
default :arp_txd <= 8'h00 ;
endcase
end
end
ETH_MAC_S1 :
begin
case (cnt_byte)
30 :arp_txd <= FPGA_MAC[47:40] ;
31 :arp_txd <= FPGA_MAC[39:32] ;
32 :arp_txd <= FPGA_MAC[31:24] ;
33 :arp_txd <= FPGA_MAC[23:16] ;
34 :arp_txd <= FPGA_MAC[15:8] ;
35 :arp_txd <= FPGA_MAC[7:0] ;
default :arp_txd <= FPGA_MAC[47:40] ;
endcase
end
ETH_IP_S1 :
begin
case (cnt_byte)
36 :arp_txd <= FPGA_IP[31:24] ;
37 :arp_txd <= FPGA_IP[23:16] ;
38 :arp_txd <= FPGA_IP[15:8] ;
39 :arp_txd <= FPGA_IP[7:0] ;
default :arp_txd <= FPGA_IP[31:24] ;
endcase
end
ETH_MAC1 :
begin
if(arp_tx_op)
arp_txd <= 8'hff ;
else
begin
case (cnt_byte)
40 :arp_txd <= des_mac[47:40] ;
41 :arp_txd <= des_mac[39:32] ;
42 :arp_txd <= des_mac[31:24] ;
43 :arp_txd <= des_mac[23:16] ;
44 :arp_txd <= des_mac[15:8] ;
45 :arp_txd <= des_mac[7:0] ;
default :arp_txd <= des_mac[47:40] ;
endcase
end
end
ETH_IP1 :
begin
case (cnt_byte)
46 :arp_txd <= PC_IP[31:24] ;
47 :arp_txd <= PC_IP[23:16] ;
48 :arp_txd <= PC_IP[15:8] ;
49 :arp_txd <= PC_IP[7:0] ;
default :arp_txd <= PC_IP[31:24] ;
endcase
end
ARP_START5 : arp_txd <= 8'h00 ;
CRC :
begin
case (cnt_byte)
68 :arp_txd <= crc_d[7:0] ;
69 :arp_txd <= crc_d[15:8] ;
70 :arp_txd <= crc_d[23:16] ;
71 :arp_txd <= crc_d[31:24] ;
default :arp_txd <= crc_d[7:0] ;
endcase
end
default : arp_txd <= 8'h00 ;
endcase
end
//arp_txv
always @(posedge arp_txc)
begin
if(!rst_n)
arp_txv <= 0 ;
else if(cur_s == IDLE)
arp_txv <= 0 ;
else
arp_txv <= 1 ;
end
//arp_tx_done
assign arp_tx_done = (cur_s == CRC && cnt_byte == 71)?1:0;
//crc_e
always @(posedge arp_txc)
begin
if(!rst_n)
crc_e <= 0 ;
else if(cur_s == IDLE || cur_s == PREAMBL || cur_s == SFD)
crc_e <= 0 ;
else
crc_e <= 1 ;
end
//crc_init
always @(posedge arp_txc)
begin
if(!rst_n)
crc_init <= 0 ;
else if(cur_s == IDLE)
crc_init <= 1 ;
else
crc_init <= 0 ;
end
endmodule【FPGA·实验证据】
【实验目标】
本节要验证什么?预期现象是什么?
【波形/截图】
用工具栏插入波形图、仿真界面或示波器照片
【仿真 log】
粘贴关键仿真输出或报错原文
【上板现象】
板卡现象、按键/数码管/接口实测结果
【结论与待改】
结论、坑点与下一步修改
评论 0