• 已绑定课时
  • 工程师可点评

实验报告 · 本节笔记 课程:中级 | FPGA工程师实战精进课程(送板卡+证书) · 第一部分 进阶接口设计篇 发布自课程云笔记 · FPGA 实验证据骨架 【本节要点】 mac层: ARP包: 28字节 ARP协议(请求或应答): 组装后的ARP请求包: 【疑问/坑点】 【可复用的代 码/思路】 ARP_TX端代码 `timescale 1ns / 1ps module ARP_TX( inp…

旭晨
7 0

实验报告 · 本节笔记

课程:中级 | 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

本节要验证什么?预期现象是什么?

用工具栏插入波形图、仿真界面或示波器照片

粘贴关键仿真输出或报错原文

板卡现象、按键/数码管/接口实测结果

结论、坑点与下一步修改

学习上下文

产出状态

工程师已阅7 位工程师