FPGA------以太网设计(1)基本模块
- [1. 协议解析](#1. 协议解析)
-
- (1)MAC层
- [(2)IP层 和 ARP层](#(2)IP层 和 ARP层)
- [(3)UDP层 和 ICMP层](#(3)UDP层 和 ICMP层)
- [2.1 MAC接收模块](#2.1 MAC接收模块)
- [2.2 MAC发送模块](#2.2 MAC发送模块)
- [3.1 IP接收模块](#3.1 IP接收模块)
- [3.2 IP发送模块](#3.2 IP发送模块)
- [4.1 UDP接收模块](#4.1 UDP接收模块)
- [4.2 UDP发送模块](#4.2 UDP发送模块)
- [5.1 ICMP接收模块](#5.1 ICMP接收模块)
- [5.2 ICMP发送模块](#5.2 ICMP发送模块)
- [6.1 ARP接收模块](#6.1 ARP接收模块)
- [6.2 ARP发送模块](#6.2 ARP发送模块)
- [6.3 ARP表模块](#6.3 ARP表模块)
- [7 CRC数据对比模块](#7 CRC数据对比模块)
- [8 MAC下ARP和IP数据分流模块](#8 MAC下ARP和IP数据分流模块)
- [9 数据流仲裁模块](#9 数据流仲裁模块)
- 模块收发组合
-
- [1 MAC层收发](#1 MAC层收发)
-
- [2 ARP层收发](#2 ARP层收发)
- [2 IP层收发](#2 IP层收发)
-
- [3 ICMP层收发](#3 ICMP层收发)
- [3 UDP层收发](#3 UDP层收发)
- UDP协议栈
1. 协议解析
每层都嵌套在上层的数据字段
(1)MAC层
以太网帧长: 64B~1518B
(2)IP层 和 ARP层
IP层
ARP层
(3)UDP层 和 ICMP层
UDP层
ICMP层
2.1 MAC接收模块
c
module MAC_rx#(
parameter P_TARTGET_MAC = {8'h00,8'h00,8'h00,8'h00,8'h00,8'h00},
P_SOURCE_MAC = {8'h00,8'h00,8'h00,8'h00,8'h00,8'h00},
P_CRC_CHECK = 1
)(
input i_clk ,
input i_rst ,
/*--------info port--------*/
input [47:0] i_target_mac ,
input i_target_mac_valid ,
input [47:0] i_source_mac ,
input i_source_mac_valid ,
/*--------data port--------*/
output [15:0] o_post_type ,
output [7 :0] o_post_data ,
output o_post_last ,
output o_post_valid ,
output [47:0] o_rec_src_mac ,
output o_rec_src_valid ,
output o_crc_error ,
output o_crc_valid ,
/*--------GMII port--------*/
input [7 :0] i_GMII_data ,
input i_GMII_valid
);
/***************function**************/
/***************parameter*************/
/***************port******************/
/***************mechine***************/
/***************reg*******************/
reg ro_post_last ;
reg ro_post_valid ;
reg [47:0] ro_rec_src_mac ;
reg ro_rec_src_valid ;
reg ro_crc_error ;
reg [7 :0] ri_GMII_data ;
reg ri_GMII_valid ;
reg [7 :0] ri_GMII_data_1d ;
reg ri_GMII_valid_1d ;
reg [7 :0] ri_GMII_data_2d ;
reg ri_GMII_valid_2d ;
reg [7 :0] ri_GMII_data_3d ;
reg ri_GMII_valid_3d ;
reg [7 :0] ri_GMII_data_4d ;
reg ri_GMII_valid_4d ;
reg [7 :0] ri_GMII_data_5d ;
reg ri_GMII_valid_5d ;
reg [47:0] r_target_mac ;
reg [47:0] r_source_mac ;
reg [47:0] r_rec_mac ;
reg r_rec_mac_access ;
reg [15:0] r_rec_cnt ;
reg r_headr_check ;
reg r_header_access ;
reg [15:0] r_rec_type ;//0x0800-IP 0X0806-ARP
reg r_crc_rst ;
reg r_crc_en ;
reg r_crc_en_1d ;
reg [15:0] r_rec_5d_cnt ;
reg [31:0] r_crc_result ;
reg ro_crc_valid ;
/***************wire******************/
wire [31:0] w_crc_result ;
/***************component*************/
CRC32_D8 CRC32_D8_u0(
.i_clk (i_clk ),
.i_rst (r_crc_rst ),
.i_en (r_crc_en ),
.i_data (ri_GMII_data_5d ),
.o_crc (w_crc_result )
);
/***************assign****************/
assign o_post_type = r_rec_type ;
assign o_post_data = ri_GMII_data_5d ;
assign o_post_last = ro_post_last ;
assign o_post_valid = ro_post_valid ;
assign o_rec_src_mac = ro_rec_src_mac ;
assign o_rec_src_valid = ro_rec_src_valid ;
assign o_crc_error = ro_crc_error ;
assign o_crc_valid = ro_crc_valid ;
/***************always****************/
//数据打5拍,为了对齐信号
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst) begin
ri_GMII_data <= 'd0;
ri_GMII_valid <= 'd0;
ri_GMII_data_1d <= 'd0;
ri_GMII_valid_1d <= 'd0;
ri_GMII_data_2d <= 'd0;
ri_GMII_valid_2d <= 'd0;
ri_GMII_data_3d <= 'd0;
ri_GMII_valid_3d <= 'd0;
ri_GMII_data_4d <= 'd0;
ri_GMII_valid_4d <= 'd0;
end else begin
ri_GMII_data <= i_GMII_data ;
ri_GMII_valid <= i_GMII_valid;
ri_GMII_data_1d <= ri_GMII_data ;
ri_GMII_valid_1d <= ri_GMII_valid;
ri_GMII_data_2d <= ri_GMII_data_1d ;
ri_GMII_valid_2d <= ri_GMII_valid_1d;
ri_GMII_data_3d <= ri_GMII_data_2d ;
ri_GMII_valid_3d <= ri_GMII_valid_2d;
ri_GMII_data_4d <= ri_GMII_data_3d ;
ri_GMII_valid_4d <= ri_GMII_valid_3d;
ri_GMII_data_5d <= ri_GMII_data_4d ;
ri_GMII_valid_5d <= ri_GMII_valid_4d;
end
end
//valid后,输入目标mac地址锁存
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst)
r_target_mac <= P_TARTGET_MAC;
else if(i_target_mac_valid)
r_target_mac <= i_target_mac;
else
r_target_mac <= r_target_mac;
end
//valid后,输入源mac地址锁存
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst)
r_source_mac <= P_SOURCE_MAC ;
else if(i_source_mac_valid)
r_source_mac <= i_source_mac;
else
r_source_mac <= r_source_mac;
end
//GMII接口输入有效
// r_rec_cnt 为 6 停一个周期 接收SFD
// 继续 + 1
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst)
r_rec_cnt <= 'd0;
else if(ri_GMII_valid && r_rec_cnt == 6 && ri_GMII_data == 8'h55)
r_rec_cnt <= r_rec_cnt;
else if(ri_GMII_valid)
r_rec_cnt <= r_rec_cnt + 1;
else
r_rec_cnt <= 'd0;
end
// r_rec_cnt 7 ~ 12 存好收到目的的MAC地址
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst)
r_rec_mac <= 'd0;
else if(ri_GMII_valid && r_rec_cnt >= 7 && r_rec_cnt <= 12)
r_rec_mac <= {r_rec_mac[39:0],ri_GMII_data};
else
r_rec_mac <= r_rec_mac;
end
// r_rec_cnt 13 检测收到目的mac与自身mac是否相等
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst)
r_rec_mac_access <= 'd0;
else if(r_rec_cnt == 13 && r_rec_mac != r_source_mac)
r_rec_mac_access <= 'd0;
else if(r_rec_cnt == 13 && (r_rec_mac == r_source_mac || &r_rec_mac))
r_rec_mac_access <= 'd1;
else
r_rec_mac_access <= r_rec_mac_access;
end
//r_rec_cnt 0~6 检验前导码 是否为55 再6 检测SFD 是否为D5
always@(*)
begin
case(r_rec_cnt)
0,1,2,3,4,5 :r_headr_check <= ri_GMII_data == 8'h55 ? 'd1 : 'd0;
6 :r_headr_check <= ri_GMII_data == 8'hD5 || ri_GMII_data == 8'h55 ? 'd1 : 'd0;
default :r_headr_check <= 'd1;
endcase
end
//头没有问题,就通过信号不拉低
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst)
r_header_access <= 'd1;
else if(!ri_GMII_valid)
r_header_access <= 'd1;
else if(ri_GMII_valid && r_rec_cnt >= 0 && r_rec_cnt <= 6 && !r_headr_check)
r_header_access <= 'd0;
else
r_header_access <= r_header_access;
end
// r_rec_cnt 13~ 18 源MAC地址接收
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst)
ro_rec_src_mac <= 'd0;
else if(ri_GMII_valid && r_rec_cnt >= 13 && r_rec_cnt <= 18)
ro_rec_src_mac <= {ro_rec_src_mac[39:0],ri_GMII_data};
else
ro_rec_src_mac <= ro_rec_src_mac;
end
// r_rec_cnt 19 源MAC地址接收有效
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst)
ro_rec_src_valid <= 'd0;
else if(r_rec_cnt == 19)
ro_rec_src_valid <= 'd1;
else
ro_rec_src_valid <= ro_rec_src_valid;
end
//r_rec_cnt 19 ~ 20 接收类型
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst)
r_rec_type <= 'd0;
else if(ri_GMII_valid && r_rec_cnt >= 19 && r_rec_cnt <= 20)
r_rec_type <= {r_rec_type[7:0],ri_GMII_data};
else
r_rec_type <= r_rec_type;
end
//延迟5个周期的 GMII 有效 r_rec_5d_cnt + 1
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst)
r_rec_5d_cnt <= 'd0;
else if(ri_GMII_valid_5d)
r_rec_5d_cnt <= r_rec_5d_cnt + 1;
else
r_rec_5d_cnt <= 'd0;
end
//正常信号的下降沿 有效为0
//延迟5个周期 计数为 21 有效为1
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst)
ro_post_valid <= 'd0;
else if(ro_post_last)
ro_post_valid <= 'd0;
else if(r_rec_5d_cnt == 21)
ro_post_valid <= 'd1;
else
ro_post_valid <= ro_post_valid;
end
//GMII有效信号下降沿 输出 ro_post_last
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst)
ro_post_last <= 'd0;
else if(!i_GMII_valid && ri_GMII_valid)
ro_post_last <= 'd1;
else
ro_post_last <= 'd0;
end
// always@(posedge i_clk,posedge i_rst)
// begin
// if(i_rst)
// ro_arp_valid <= 'd0;
// else if(!ri_GMII_valid && ri_GMII_data_1d)
// ro_arp_valid <= 'd0;
// else if(r_rec_type == 16'h0806 && r_rec_5d_cnt == 20)
// ro_arp_valid <= 'd1;
// else
// ro_arp_valid <= ro_ip_valid;
// end
// always@(posedge i_clk,posedge i_rst)
// begin
// if(i_rst)
// ro_arp_last <= 'd0;
// else if(!i_GMII_valid && ri_GMII_valid && r_rec_type == 16'h0806)
// ro_arp_last <= 'd1;
// else
// ro_arp_last <= 'd0;
// end
//CRC使能信号 来 CRC模块数据复位信号
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst)
r_crc_rst <= 'd1;
else if(r_rec_5d_cnt == 7)
r_crc_rst <= 'd0;
else if(!r_crc_en && r_crc_en_1d)
r_crc_rst <= 'd1;
else
r_crc_rst <= r_crc_rst;
end
// GMII有效的下降沿 关闭crc校验使能
//
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst)
r_crc_en <= 'd0;
else if(!ri_GMII_valid && ri_GMII_data_1d)
r_crc_en <= 'd0;
else if(r_rec_5d_cnt == 7)
r_crc_en <= 'd1;
else
r_crc_en <= r_crc_en;
end
//CRC使能信号打拍
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst)
r_crc_en_1d <= 'd0;
else
r_crc_en_1d <= r_crc_en;
end
//获取外部输入的CRC结果
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst)
r_crc_result <= 'd0;
else if(ri_GMII_valid)
r_crc_result <= {ri_GMII_data,r_crc_result[31:8]};
else
r_crc_result <= r_crc_result;
end
//CRC使能下降沿 CRC有效
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst)
ro_crc_valid <= 'd0;
else if(!r_crc_en && r_crc_en_1d)
ro_crc_valid <= 'd1;
else
ro_crc_valid <= 'd0;
end
//CRC校验 error
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst)
ro_crc_error <= 'd0;
else if(!P_CRC_CHECK)
ro_crc_error <= 'd0;
else if(!r_crc_en && r_crc_en_1d && r_crc_result != w_crc_result)
ro_crc_error <= 'd1;
else
ro_crc_error <= 'd0;
end
endmodule
2.2 MAC发送模块
c
module MAC_tx#(
parameter P_TARTGET_MAC = {8'h00,8'h00,8'h00,8'h00,8'h00,8'h00},
P_SOURCE_MAC = {8'h00,8'h00,8'h00,8'h00,8'h00,8'h00},
P_CRC_CHECK = 1
)(
input i_clk ,
input i_rst ,
/*--------info port--------*/
input [47:0] i_target_mac ,
input i_target_mac_valid ,
input [47:0] i_source_mac ,
input i_source_mac_valid ,
/*--------data port--------*/
input i_udp_valid ,
output o_udp_ready ,
input [15:0] i_send_type ,
input [15:0] i_send_len ,
input [7 :0] i_send_data ,
input i_send_last ,
input i_send_valid ,
/*--------GMII port--------*/
output [7 :0] o_GMII_data ,
output o_GMII_valid
);
/***************function**************/
/***************parameter*************/
/***************port******************/
/***************mechine***************/
/***************reg*******************/
reg [15:0] ri_send_type ;
reg [15:0] ri_send_len ;
reg [7 :0] ri_send_data ;
reg ri_send_valid ;
reg ri_send_valid_1d ;
reg [7 :0] ro_GMII_data ;
reg ro_GMII_valid ;
reg ro_GMII_valid_1d ;
reg [47:0] r_target_mac ;
reg [47:0] r_source_mac ;
reg r_fifo_mac_rd_en ;
reg [15:0] r_mac_pkg_cnt ;
reg [7 :0] r_mac_data ;
reg r_mac_data_valid ;
reg r_mac_data_valid_1d ;
reg [15:0] r_mac_data_cnt ;
reg r_crc_rst ;
reg r_crc_en ;
reg [1 :0] r_crc_out_cnt ;
reg r_crc_out_cnt_1d ;
reg [15:0] r_gap_lat ;
reg r_gap_lock ;
reg [15:0] r_gap_cnt ;
reg ri_udp_valid ;
reg ro_udp_ready ;
/***************wire******************/
wire [7 :0] w_fifo_mac_dout ;
wire w_fifo_mac_full ;
wire w_fifo_mac_empty ;
wire w_send_valid_pos ;
wire w_send_valid_neg ;
wire [31:0] w_crc_result ;
/***************component*************/
FIFO_MAC_8X64 FIFO_MAC_8X64_U0 (
.clk (i_clk ), // input wire clk
.din (ri_send_data ), // input wire [7 : 0] din
.wr_en (ri_send_valid ), // input wire wr_en
.rd_en (r_fifo_mac_rd_en ), // input wire rd_en
.dout (w_fifo_mac_dout ), // output wire [7 : 0] dout
.full (w_fifo_mac_full ), // output wire full
.empty (w_fifo_mac_empty ) // output wire empty
);
CRC32_D8 CRC32_D8_u0(
.i_clk (i_clk ),
.i_rst (r_crc_rst ),
.i_en (r_crc_en ),
.i_data (r_mac_data ),
.o_crc (w_crc_result )
);
/***************assign****************/
assign o_GMII_data = ro_GMII_data ;
assign o_GMII_valid = ro_GMII_valid ;
assign w_send_valid_pos = ri_send_valid & !ri_send_valid_1d;
assign w_send_valid_neg = !ri_send_valid & ri_send_valid_1d;
assign o_udp_ready = ro_udp_ready ;
/***************always****************/
//锁存 目的mac
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst)
r_target_mac <= P_TARTGET_MAC;
else if(i_target_mac_valid)
r_target_mac <= i_target_mac;
else
r_target_mac <= r_target_mac;
end
//锁存 源mac
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst)
r_source_mac <= P_SOURCE_MAC ;
else if(i_source_mac_valid)
r_source_mac <= i_source_mac;
else
r_source_mac <= r_source_mac;
end
//锁存输入的 发送mac帧信息
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst) begin
ri_send_type <= 'd0;
ri_send_len <= 'd0;
ri_send_data <= 'd0;
ri_send_valid <= 'd0;
end else if(i_send_valid) begin
ri_send_type <= i_send_type ;
ri_send_len <= i_send_len ;
ri_send_data <= i_send_data ;
ri_send_valid <= i_send_valid;
end else begin
ri_send_type <= ri_send_type ;
ri_send_len <= ri_send_len ;
ri_send_data <= 'd0 ;
ri_send_valid <= 'd0;
end
end
//mac帧的计数器
//CRC校验输出完成 停止
//输入信号有效上升沿开始 计数
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst)
r_mac_pkg_cnt <= 'd0;
else if(r_crc_out_cnt == 3)
r_mac_pkg_cnt <= 'd0;
else if(w_send_valid_pos || r_mac_pkg_cnt)
r_mac_pkg_cnt <= r_mac_pkg_cnt + 1;
else
r_mac_pkg_cnt <= r_mac_pkg_cnt;
end
//组mac帧 : 前导码 + SFD + 目的mac + 源mac
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst)
r_mac_data <= 'd0;
else case(r_mac_pkg_cnt)
0,1,2,3,4,5,6 :r_mac_data <= 8'h55;
7 :r_mac_data <= 8'hd5;
8 :r_mac_data <= ri_send_type == 16'h0806 ? 8'hff : r_target_mac[47:40];
9 :r_mac_data <= ri_send_type == 16'h0806 ? 8'hff : r_target_mac[39:32];
10 :r_mac_data <= ri_send_type == 16'h0806 ? 8'hff : r_target_mac[31:24];
11 :r_mac_data <= ri_send_type == 16'h0806 ? 8'hff : r_target_mac[23:16];
12 :r_mac_data <= ri_send_type == 16'h0806 ? 8'hff : r_target_mac[15: 8];
13 :r_mac_data <= ri_send_type == 16'h0806 ? 8'hff : r_target_mac[7 : 0];
14 :r_mac_data <= r_source_mac[47:40];
15 :r_mac_data <= r_source_mac[39:32];
16 :r_mac_data <= r_source_mac[31:24];
17 :r_mac_data <= r_source_mac[23:16];
18 :r_mac_data <= r_source_mac[15: 8];
19 :r_mac_data <= r_source_mac[7 : 0];
20 :r_mac_data <= ri_send_type[15: 8];
21 :r_mac_data <= ri_send_type[7 : 0];
default :r_mac_data <= w_fifo_mac_dout;
endcase
end
//mac有效信号
// mac数据计数到值 关闭
//发送有效上升沿 开启
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst)
r_mac_data_valid <= 'd0;
else if(r_mac_data_cnt == ri_send_len + 1)
r_mac_data_valid <= 'd0;
else if(w_send_valid_pos)
r_mac_data_valid <= 'd1;
else
r_mac_data_valid <= r_mac_data_valid;
end
//mac总数计数器
//到设置长度清零
//fifo读使能 开启计数
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst)
r_mac_data_cnt <= 'd0;
else if(r_mac_data_cnt == ri_send_len + 1)
r_mac_data_cnt <= 'd0;
else if(r_fifo_mac_rd_en | r_mac_data_cnt)
r_mac_data_cnt <= r_mac_data_cnt + 1;
else
r_mac_data_cnt <= r_mac_data_cnt;
end
//mac帧的计数器 到20 开启读fifo使能
//到mac总数关闭
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst)
r_fifo_mac_rd_en <= 'd0;
else if(r_mac_data_cnt == ri_send_len - 1)
r_fifo_mac_rd_en <= 'd0;
else if(r_mac_pkg_cnt == 20)
r_fifo_mac_rd_en <= 'd1;
else
r_fifo_mac_rd_en <= r_fifo_mac_rd_en;
end
//CRC校验复位
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst)
r_crc_rst <= 'd1;
else if(r_mac_pkg_cnt == 8 )
r_crc_rst <= 'd0;
else if(r_crc_out_cnt == 3)
r_crc_rst <= 'd1;
else
r_crc_rst <= r_crc_rst;
end
//CRC校验使能,mac帧计时器为 8时 开启
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst)
r_crc_en <= 'd0;
else if(r_mac_data_cnt == ri_send_len + 1)
r_crc_en <= 'd0;
else if(r_mac_pkg_cnt == 8 )
r_crc_en <= 'd1;
else
r_crc_en <= r_crc_en;
end
// r_crc_out_cnt 数据有效下降沿开启计数 等于3清零
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst)
r_crc_out_cnt <= 'd0;
else if(r_crc_out_cnt == 3)
r_crc_out_cnt <= 'd0;
else if((!r_mac_data_valid && r_mac_data_valid_1d) || r_crc_out_cnt)
r_crc_out_cnt <= r_crc_out_cnt + 1;
else
r_crc_out_cnt <= r_crc_out_cnt;
end
//输出mac帧数据
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst)
ro_GMII_data <= 'd0;
else if(r_mac_data_valid)
ro_GMII_data <= r_mac_data;
else case(r_crc_out_cnt)
0 :ro_GMII_data <= w_crc_result[7 : 0];
1 :ro_GMII_data <= w_crc_result[15: 8];
2 :ro_GMII_data <= w_crc_result[23:16];
3 :ro_GMII_data <= w_crc_result[31:24];
default :ro_GMII_data <= 'd0;
endcase
end
// r_crc_out_cnt_1d
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst)
r_crc_out_cnt_1d <= 'd0;
else if(r_crc_out_cnt == 3)
r_crc_out_cnt_1d <= 'd1;
else
r_crc_out_cnt_1d <= 'd0;
end
//数据有效的时候 GMII输出有效
//只有在CRC结束,r_crc_out_cnt_1d 拉高的时候,GMII输出无效
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst)
ro_GMII_valid <= 'd0;
else if(r_crc_out_cnt_1d)
ro_GMII_valid <= 'd0;
else if(r_mac_data_valid)
ro_GMII_valid <= 'd1;
else
ro_GMII_valid <= ro_GMII_valid;
end
//信号打拍 获得上升沿
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst) begin
ri_send_valid_1d <= 'd0;
r_mac_data_valid_1d <= 'd0;
end else begin
ri_send_valid_1d <= ri_send_valid ;
r_mac_data_valid_1d <= r_mac_data_valid;
end
end
/*-------------------UDP------------------------*/
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst) begin
ri_udp_valid <= 'd0 ;
ro_GMII_valid_1d <= 'd0;
end else begin
ri_udp_valid <= i_udp_valid;
ro_GMII_valid_1d <= ro_GMII_valid;
end
end
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst)
ro_udp_ready <= 'd1;
else if(i_udp_valid)
ro_udp_ready <= 'd0;
else if( r_mac_data_cnt == ri_send_len - 1)
ro_udp_ready <= 'd1;
else
ro_udp_ready <= ro_udp_ready;
end
endmodule
3.1 IP接收模块
c
module IP_rx#(
parameter P_ST_TARGET_IP = {8'd192,8'd168,8'd1,8'd0},
parameter P_ST_SOURCE_IP = {8'd192,8'd168,8'd1,8'd1}
)(
input i_clk ,
input i_rst ,
/*--------info port --------*/
input [31:0] i_target_ip ,
input i_target_valid ,
input [31:0] i_source_ip ,
input i_source_valid ,
/*--------data port--------*/
output [15:0] o_udp_len ,
output [7 :0] o_udp_data ,
output o_udp_last ,
output o_udp_valid ,
output [15:0] o_icmp_len ,
output [7 :0] o_icmp_data ,
output o_icmp_last ,
output o_icmp_valid ,
output [31:0] o_source_ip ,
output o_source_ip_valid ,
/*--------mac port--------*/
input [7 :0] i_mac_data ,
input i_mac_last ,
input i_mac_valid
);
/***************function**************/
/***************parameter*************/
/***************port******************/
/***************mechine***************/
/***************reg*******************/
reg [31:0] r_target_ip ;
reg [31:0] r_source_ip ;
reg [7 :0] ri_mac_data ;
reg [7 :0] ri_mac_data_1d ;
reg ri_mac_last ;
reg ri_mac_valid ;
reg ri_mac_valid_1d ;
reg [15:0] ro_udp_len ;
reg ro_udp_last ;
reg ro_udp_valid ;
reg [15:0] ro_icmp_len ;
reg ro_icmp_last ;
reg ro_icmp_valid ;
reg [15:0] r_ip_len ;
reg [7 :0] r_ip_type ;
reg [31:0] r_ip_source ;
reg [31:0] r_ip_target ;
reg [15:0] r_ip_cnt ;
reg ro_source_ip_valid ;
/***************wire******************/
/***************component*************/
/***************assign****************/
assign o_udp_data = ri_mac_data_1d ;
assign o_icmp_data = ri_mac_data_1d ;
assign o_udp_len = ro_udp_len ;
assign o_udp_last = ro_udp_last ;
assign o_udp_valid = ro_udp_valid ;
assign o_icmp_len = ro_icmp_len ;
assign o_icmp_last = ro_icmp_last ;
assign o_icmp_valid = ro_icmp_valid ;
assign o_source_ip = r_ip_source ;
assign o_source_ip_valid = ro_source_ip_valid;
/***************always****************/
//目的ip有效信号 锁存 目的ip
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst)
r_target_ip <= P_ST_TARGET_IP;
else if(i_target_valid)
r_target_ip <= i_target_ip;
else
r_target_ip <= r_target_ip;
end
//源ip效信号 锁存 源ip
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst)
r_source_ip <= P_ST_SOURCE_IP;
else if(i_source_valid)
r_source_ip <= i_source_ip;
else
r_source_ip <= r_source_ip;
end
//信号和数据打拍
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst) begin
ri_mac_data <= 'd0;
ri_mac_last <= 'd0;
ri_mac_valid <= 'd0;
ri_mac_data_1d <= 'd0;
ri_mac_valid_1d <= 'd0;
end else begin
ri_mac_data <= i_mac_data ;
ri_mac_last <= i_mac_last ;
ri_mac_valid <= i_mac_valid;
ri_mac_data_1d <= ri_mac_data;
ri_mac_valid_1d <= ri_mac_valid;
end
end
//mac端口有效 ip计数器+1
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst)
r_ip_cnt <= 'd0;
else if(ri_mac_valid)
r_ip_cnt <= r_ip_cnt + 1;
else
r_ip_cnt <= 'd0;
end
// 2 3 字节数据为ip报文总长度
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst)
r_ip_len <= 'd0;
else if(r_ip_cnt >= 2 && r_ip_cnt <= 3)
r_ip_len <= {r_ip_len[7:0],ri_mac_data};
else
r_ip_len <= r_ip_len;
end
//第9字节 ip 协议类型
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst)
r_ip_type <= 'd0;
else if(r_ip_cnt == 9)
r_ip_type <= ri_mac_data;
else
r_ip_type <= r_ip_type;
end
//第12 13 14 15字节 ip源地址
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst)
r_ip_source <= 'd0;
else if(r_ip_cnt >= 12 && r_ip_cnt <= 15)
r_ip_source <= {r_ip_source[23:0],ri_mac_data};
else
r_ip_source <= r_ip_source;
end
//输出ip源地址有效
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst)
ro_source_ip_valid <= 'd0;
else if(r_ip_cnt == 15)
ro_source_ip_valid <= 'd1;
else
ro_source_ip_valid <= 'd0;
end
//第16 17 18 19字节 ip目的地址
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst)
r_ip_target <= 'd0;
else if(r_ip_cnt >= 16 && r_ip_cnt <= 19)
r_ip_target <= {r_ip_target[23:0],ri_mac_data};
else
r_ip_target <= r_ip_target;
end
//计算UDP 或者 ICMP 的数据长度
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst) begin
ro_udp_len <= 'd0;
ro_icmp_len <= 'd0;
end else begin
ro_udp_len <= r_ip_len - 20;
ro_icmp_len <= r_ip_len - 20;
end
end
// 第20字节 检测是目的和源IP是否正确
//检测协议类型 UDP还是ICMP
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst)
ro_udp_valid <= 'd0;
else if(!ri_mac_valid && ri_mac_valid_1d)
ro_udp_valid <= 'd0;
else if(r_ip_cnt == 20 && r_ip_target == r_source_ip && r_ip_type == 17)
ro_udp_valid <= 'd1;
else
ro_udp_valid <= ro_udp_valid;
end
//ICMP 同上
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst)
ro_icmp_valid <= 'd0;
else if(!ri_mac_valid && ri_mac_valid_1d)
ro_icmp_valid <= 'd0;
else if(r_ip_cnt == 20 && r_ip_target == r_source_ip && r_ip_type == 1)
ro_icmp_valid <= 'd1;
else
ro_icmp_valid <= ro_icmp_valid;
end
//i_mac_valid 信号的下降沿 拉高 last信号
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst)
ro_udp_last <= 'd0;
else if(!i_mac_valid && ri_mac_valid && r_ip_type == 17)
ro_udp_last <= 'd1;
else
ro_udp_last <= 'd0;
end
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst)
ro_icmp_last <= 'd0;
else if(!i_mac_valid && ri_mac_valid && r_ip_type == 1)
ro_icmp_last <= 'd1;
else
ro_icmp_last <= 'd0;
end
endmodule
3.2 IP发送模块
c
module IP_tx#(
parameter P_ST_TARGET_IP = {8'd192,8'd168,8'd1,8'd0},
parameter P_ST_SOURCE_IP = {8'd192,8'd168,8'd1,8'd1}
)(
input i_clk ,
input i_rst ,
/*--------info port --------*/
input [31:0] i_target_ip ,
input i_target_valid ,
input [31:0] i_source_ip ,
input i_source_valid ,
/*--------data port--------*/
input [7 :0] i_send_type ,
input [15:0] i_send_len ,
input [7 :0] i_send_data ,
input i_send_last ,
input i_send_valid ,
output [31:0] o_arp_seek_ip ,
output o_arp_seek_valid ,
/*--------mac port--------*/
output [15:0] o_mac_type ,
output [15:0] o_mac_len ,
output [7 :0] o_mac_data ,
output o_mac_last ,
output o_mac_valid
);
/***************function**************/
/***************parameter*************/
/***************port******************/
/***************mechine***************/
/***************reg*******************/
reg [31:0] r_target_ip ;
reg [31:0] r_source_ip ;
reg [7 :0] ri_send_type ;
reg [15:0] ri_send_len ;
reg [7 :0] ri_send_data ;
reg ri_send_last ;
reg ri_send_valid ;
reg ri_send_valid_1d ;
reg r_fifo_ip_rd_en ;
reg [7 :0] r_ip_data ;
reg [7 :0] r_ip_valid ;
reg [15:0] r_ip_data_cnt ;
reg [15:0] r_ip_message ;
reg [31:0] r_ip_check ;
reg [15:0] ro_mac_type ;
reg ro_mac_last ;
reg [31:0] ro_arp_seek_ip ;
reg ro_arp_seek_valid ;
/***************wire******************/
wire [31:0] w_fifo_ip_dout ;
wire w_fifo_ip_full ;
wire w_fifo_ip_empty ;
/***************component*************/
//把要发送的数据存进FIFO,要发送时读出来
FIFO_MAC_8X64 FIFO_IP_8X64_U0 (
.clk (i_clk ), // input wire clk
.din (ri_send_data ), // input wire [7 : 0] din
.wr_en (ri_send_valid ), // input wire wr_en
.rd_en (r_fifo_ip_rd_en ), // input wire rd_en
.dout (w_fifo_ip_dout ), // output wire [7 : 0] dout
.full (w_fifo_ip_full ), // output wire full
.empty (w_fifo_ip_empty ) // output wire empty
);
/***************assign****************/
assign o_mac_data = r_ip_data ;
assign o_mac_valid = r_ip_valid ;
assign o_mac_len = ri_send_len;
assign o_mac_type = ro_mac_type;
assign o_mac_last = ro_mac_last;
assign o_arp_seek_ip = ro_arp_seek_ip ;
assign o_arp_seek_valid = ro_arp_seek_valid;
/***************always****************/
//目的地址有效 锁存
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst)
r_target_ip <= P_ST_TARGET_IP;
else if(i_target_valid)
r_target_ip <= i_target_ip;
else
r_target_ip <= r_target_ip;
end
//源地址有效 锁存
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst)
r_source_ip <= P_ST_SOURCE_IP;
else if(i_source_valid)
r_source_ip <= i_source_ip;
else
r_source_ip <= r_source_ip;
end
//锁存 类型和数据等信息 ip报文长度 为 UDP报文 + 20
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst) begin
ri_send_type <= 'd0;
ri_send_len <= 'd0;
ri_send_data <= 'd0;
ri_send_last <= 'd0;
ri_send_valid <= 'd0;
end else if(i_send_valid) begin
ri_send_type <= i_send_type ;
ri_send_len <= i_send_len + 20;
ri_send_data <= i_send_data ;
ri_send_last <= i_send_last ;
ri_send_valid <= i_send_valid ;
end else begin
ri_send_type <= ri_send_type ;
ri_send_len <= ri_send_len ;
ri_send_data <= ri_send_data ;
ri_send_last <= 'd0;
ri_send_valid <= 'd0;
end
end
// r_ip_data_cnt 计数
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst)
r_ip_data_cnt <= 'd0;
else if(r_ip_data_cnt == ri_send_len - 1)
r_ip_data_cnt <= 'd0;
else if(ri_send_valid || r_ip_data_cnt)
r_ip_data_cnt <= r_ip_data_cnt + 1;
else
r_ip_data_cnt <= r_ip_data_cnt;
end
// ip报文的个数 计数
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst)
r_ip_message <= 'd0;
else if(o_mac_last)
r_ip_message <= r_ip_message + 1;
else
r_ip_message <= r_ip_message;
end
//进行首部校验和
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst)
r_ip_check <= 'd0;
else if(ri_send_valid && r_ip_data_cnt == 0)
r_ip_check <= 16'h4500 + ri_send_len + r_ip_message + 16'h4000 + {8'd64,ri_send_type} + r_source_ip[31:16] +
r_source_ip[15:0] + r_target_ip[31:16] + r_target_ip[15:0];
else if(r_ip_data_cnt == 1)
r_ip_check <= r_ip_check[31:16] + r_ip_check[15:0];
else if(r_ip_data_cnt == 2)
r_ip_check <= r_ip_check[31:16] + r_ip_check[15:0];
else if(r_ip_data_cnt == 3)
r_ip_check <= ~r_ip_check;
else
r_ip_check <= r_ip_check;
end
//打拍生成边沿
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst)
ri_send_valid_1d <= 'd0;
else
ri_send_valid_1d <= ri_send_valid;
end
//发送有效信号上升沿 ip帧有效拉高
// mac帧结束信号拉高,ip帧有效拉低
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst)
r_ip_valid <= 'd0;
else if(ro_mac_last)
r_ip_valid <= 'd0;
else if(ri_send_valid && !ri_send_valid_1d)
r_ip_valid <= 'd1;
else
r_ip_valid <= r_ip_valid;
end
//组帧输出
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst)
r_ip_data <= 'd0;
else case(r_ip_data_cnt)
0 : r_ip_data <= {4'b0100,4'b0101}; //版本+首部长度
1 : r_ip_data <= 'd0; //服务类型
2 : r_ip_data <= ri_send_len[15:8]; //总长度的高8位
3 : r_ip_data <= ri_send_len[7 :0]; //总长度的低8位
4 : r_ip_data <= r_ip_message[15:8]; //报文标识的高8位
5 : r_ip_data <= r_ip_message[7 :0]; //报文标识的低8位
6 : r_ip_data <= {3'b010,5'b00000}; //标志+片偏移
7 : r_ip_data <= 'd0; //片偏移
8 : r_ip_data <= 'd64; //生存时间
9 : r_ip_data <= ri_send_type; //协议类型
10 : r_ip_data <= r_ip_check[15:8];
11 : r_ip_data <= r_ip_check[7 :0];
12 : r_ip_data <= r_source_ip[31:24];
13 : r_ip_data <= r_source_ip[23:16];
14 : r_ip_data <= r_source_ip[15:8];
15 : r_ip_data <= r_source_ip[7 :0];
16 : r_ip_data <= r_target_ip[31:24];
17 : r_ip_data <= r_target_ip[23:16];
18 : r_ip_data <= r_target_ip[15:8];
19 : r_ip_data <= r_target_ip[7 :0];
default : r_ip_data <= w_fifo_ip_dout;
endcase
end
// ip帧 计数到18 从FIFO中读取数据
// mac帧结束信号拉高,不读了
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst)
r_fifo_ip_rd_en <= 'd0;
else if(ro_mac_last)
r_fifo_ip_rd_en <= 'd0;
else if(r_ip_data_cnt == 18)
r_fifo_ip_rd_en <= 'd1;
else
r_fifo_ip_rd_en <= r_fifo_ip_rd_en;
end
//ip帧计数器计到最大 mac 帧结束了
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst)
ro_mac_last <= 'd0;
else if(r_ip_data_cnt == ri_send_len - 1)
ro_mac_last <= 'd1;
else
ro_mac_last <= 'd0;
end
//输出mac层的报文类型
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst) begin
ro_mac_type <= 'd0;
end else begin
ro_mac_type <= 16'h0800;
end
end
//ARP
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst) begin
ro_arp_seek_ip <= P_ST_TARGET_IP;
ro_arp_seek_valid <= 'd0;
end else if(ri_send_valid && !ri_send_valid_1d) begin
ro_arp_seek_ip <= r_target_ip;
ro_arp_seek_valid <= 'd1;
end else begin
ro_arp_seek_ip <= ro_arp_seek_ip;
ro_arp_seek_valid <= 'd0;
end
end
endmodule
4.1 UDP接收模块
c
module UDP_rx#(
parameter P_TARGET_PORT = 16'h8080 ,
P_SOURCE_PORT = 16'h8080
)(
input i_clk ,
input i_rst ,
/*--------info port-------*/
input [15:0] i_target_port ,
input i_target_valid ,
input [15:0] i_source_port ,
input i_source_valid ,
/*--------data port--------*/
output [15:0] o_udp_len ,
output [7 :0] o_udp_data ,
output o_udp_last ,
output o_udp_valid ,
/*--------ip port--------*/
input [15:0] i_ip_len ,
input [7 :0] i_ip_data ,
input i_ip_last ,
input i_ip_valid
);
/***************function**************/
/***************parameter*************/
/***************port******************/
/***************mechine***************/
/***************reg*******************/
reg [15:0] r_target_port ;
reg [15:0] r_source_port ;
reg [15:0] ri_ip_len ;
reg [7 :0] ri_ip_data ;
reg ri_ip_last ;
reg ri_ip_valid ;
reg [15:0] ro_udp_len ;
reg ro_udp_last ;
reg ro_udp_valid ;
reg [15:0] r_udp_cnt ;
/***************wire******************/
/***************component*************/
/***************assign****************/
assign o_udp_len = ro_udp_len ;
assign o_udp_data = ri_ip_data ;
assign o_udp_last = ro_udp_last ;
assign o_udp_valid = ro_udp_valid ;
/***************always****************/
//锁存 目标端口
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst)
r_target_port <= 'd0;
else if(i_target_valid)
r_target_port <= i_target_port;
else
r_target_port <= r_target_port;
end
//锁存 源端口
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst)
r_source_port <= 'd0;
else if(i_source_valid)
r_source_port <= i_source_port;
else
r_source_port <= r_source_port;
end
//ip有效信号 锁存ip的信息
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst) begin
ri_ip_len <= 0;
ri_ip_data <= 0;
ri_ip_last <= 0;
ri_ip_valid <= 0;
end else if(i_ip_valid) begin
ri_ip_len <= i_ip_len ;
ri_ip_data <= i_ip_data ;
ri_ip_last <= i_ip_last ;
ri_ip_valid <= i_ip_valid;
end else begin
ri_ip_len <= ri_ip_len ;
ri_ip_data <= 'd0 ;
ri_ip_last <= 'd0 ;
ri_ip_valid <= 'd0;
end
end
//ip有效信号,r_udp_cnt + 1
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst)
r_udp_cnt <= 'd0;
else if(ri_ip_valid)
r_udp_cnt <= r_udp_cnt + 1;
else
r_udp_cnt <= 'd0;
end
//UDP帧的长度 为 IP帧长度 - 8
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst)
ro_udp_len <= 'd0;
else
ro_udp_len <= ri_ip_len - 8;
end
//UDP接收到第7位 拉高UDP有效,跟数据一起出来
//UDP发送到长度-1 时,拉低有效信号
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst)
ro_udp_valid <= 'd0;
else if(r_udp_cnt == ri_ip_len - 1)
ro_udp_valid <= 'd0;
else if(r_udp_cnt == 7)
ro_udp_valid <= 'd1;
else
ro_udp_valid <= ro_udp_valid;
end
//拉高last结束信号
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst)
ro_udp_last <= 'd0;
else if(r_udp_cnt == ri_ip_len - 2)
ro_udp_last <= 'd1;
else
ro_udp_last <= 'd0;
end
endmodule
4.2 UDP发送模块
c
module UDP_tx#(
parameter P_TARGET_PORT = 16'h8080 ,
P_SOURCE_PORT = 16'h8080
)(
input i_clk ,
input i_rst ,
/*--------info port-------*/
input [15:0] i_target_port ,
input i_target_valid ,
input [15:0] i_source_port ,
input i_source_valid ,
/*--------data port--------*/
input [15:0] i_send_len ,
input [7 :0] i_send_data ,
input i_send_last ,
input i_send_valid ,
/*--------ip port--------*/
output [15:0] o_ip_len ,
output [7 :0] o_ip_data ,
output o_ip_last ,
output o_ip_valid
);
/***************function**************/
/***************parameter*************/
localparam P_ST_MIN_LEN = 18 + 8;
/***************port******************/
/***************mechine***************/
/***************reg*******************/
reg [15:0] r_target_port ;
reg [15:0] r_source_port ;
reg [15:0] ri_send_len ;
reg [7 :0] ri_send_data ;
reg ri_send_last ;
reg ri_send_valid ;
reg [15:0] ro_ip_len ;
reg [7 :0] ro_ip_data ;
reg ro_ip_last ;
reg ro_ip_valid ;
reg r_fifo_udp_rd_en;
reg [15:0] r_udp_cnt ;
reg r_fifo_udp_empty;
/***************wire******************/
wire [7:0] w_fifo_udp_dout ;
wire w_fifo_udp_full ;
wire w_fifo_udp_empty;
/***************component*************/
//要写的数据存进FIFO
FIFO_MAC_8X64 FIFO_UDP_8X64_U0 (
.clk (i_clk ), // input wire clk
.din (ri_send_data ), // input wire [7 : 0] din
.wr_en (ri_send_valid ), // input wire wr_en
.rd_en (r_fifo_udp_rd_en ), // input wire rd_en
.dout (w_fifo_udp_dout ), // output wire [7 : 0] dout
.full (w_fifo_udp_full ), // output wire full
.empty (w_fifo_udp_empty ) // output wire empty
);
/***************assign****************/
assign o_ip_len = ro_ip_len ;
assign o_ip_data = ro_ip_data ;
assign o_ip_last = ro_ip_last ;
assign o_ip_valid = ro_ip_valid ;
/***************always****************/
//锁存 目的端口
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst)
r_target_port <= P_TARGET_PORT;
else if(i_target_valid)
r_target_port <= i_target_port;
else
r_target_port <= r_target_port;
end
//锁存 源端口
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst)
r_source_port <= P_SOURCE_PORT;
else if(i_source_valid)
r_source_port <= i_source_port;
else
r_source_port <= r_source_port;
end
//锁存输入的IP数据
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst) begin
ri_send_data <= 'd0;
ri_send_last <= 'd0;
ri_send_valid <= 'd0;
end else begin
ri_send_data <= i_send_data ;
ri_send_last <= i_send_last ;
ri_send_valid <= i_send_valid;
end
end
//锁存输入的数据长度
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst)
ri_send_len <= 'd0;
else if(i_send_valid)
ri_send_len <= i_send_len ;
else
ri_send_len <= ri_send_len;
end
//发送UDP数据长度小于18 并且已经完成18+8 的UDP帧 ,后计数器清空
//大于18 ,正常发完
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst)
r_udp_cnt <= 'd0;
else if(ri_send_len < 18 && r_udp_cnt == P_ST_MIN_LEN - 1)
r_udp_cnt <= 'd0;
else if(ri_send_len >= 18 && r_udp_cnt == (ri_send_len + 8) - 1)
r_udp_cnt <= 'd0;
else if(ri_send_valid || r_udp_cnt)
r_udp_cnt <= r_udp_cnt + 1;
else
r_udp_cnt <= r_udp_cnt;
end
//如果数据长度小于18 就默认18
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst)
ro_ip_len <= 'd0;
else if(ri_send_len < 18)
ro_ip_len <= 18;
else
ro_ip_len <= ri_send_len + 8;
end
//如果收到ip_last信号,ip有效拉低
//收到输入有效信号,ip有效拉高
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst)
ro_ip_valid <= 'd0;
else if(ro_ip_last)
ro_ip_valid <= 'd0;
else if(ri_send_valid)
ro_ip_valid <= 'd1;
else
ro_ip_valid <= ro_ip_valid;
end
//UDP发完后,拉高ip_last信号
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst)
ro_ip_last <= 'd0;
else if(ri_send_len < 18 && r_udp_cnt == P_ST_MIN_LEN - 1)
ro_ip_last <= 'd1;
else if(ri_send_len >= 18 && r_udp_cnt == (ri_send_len + 8) - 1)
ro_ip_last <= 'd1;
else
ro_ip_last <= 'd0;
end
//输出完8字节 UDP帧的头 FIFO读使能打开
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst)
r_fifo_udp_rd_en <= 'd0;
else if(r_udp_cnt == (ri_send_len + 8) - 1)
r_fifo_udp_rd_en <= 'd0;
else if(r_udp_cnt == 6)
r_fifo_udp_rd_en <= 'd1;
else
r_fifo_udp_rd_en <= r_fifo_udp_rd_en;
end
//空信号打拍
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst)
r_fifo_udp_empty <= 'd0;
else
r_fifo_udp_empty <= w_fifo_udp_empty;
end
//组帧输出
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst)
ro_ip_data <= 'd0;
else case(r_udp_cnt)
0 : ro_ip_data <= r_source_port[15:8];
1 : ro_ip_data <= r_source_port[7 :0];
2 : ro_ip_data <= r_target_port[15:8];
3 : ro_ip_data <= r_target_port[7 :0];
4 : ro_ip_data <= ro_ip_len[15:8];
5 : ro_ip_data <= ro_ip_len[7 :0];
6 : ro_ip_data <= 'd0;
7 : ro_ip_data <= 'd0;
default : ro_ip_data <= !r_fifo_udp_empty ? w_fifo_udp_dout : 'd0;
endcase
end
endmodule
5.1 ICMP接收模块
c
module ICMP_rx(
input i_clk ,
input i_rst ,
/*--------rec port--------*/
input [15:0] i_icmp_len ,
input [7 :0] i_icmp_data ,
input i_icmp_last ,
input i_icmp_valid ,
/*--------send port--------*/
output o_trig_reply ,
output [15:0] o_trig_seq
);
/***************function**************/
/***************parameter*************/
/***************port******************/
/***************mechine***************/
/***************reg*******************/
reg [15:0] ri_icmp_len ;
reg [7 :0] ri_icmp_data ;
reg ri_icmp_last ;
reg ri_icmp_valid ;
reg ro_trig_reply ;
reg [15:0] r_icmp_cnt ;
reg [7 :0] r_type ;
reg [15:0] ro_trig_seq ;
/***************wire******************/
/***************component*************/
/***************assign****************/
assign o_trig_reply = ro_trig_reply ;
assign o_trig_seq = ro_trig_seq ;
/***************always****************/
//输入信号打拍
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst) begin
ri_icmp_len <= 'd0;
ri_icmp_data <= 'd0;
ri_icmp_last <= 'd0;
ri_icmp_valid <= 'd0;
end else begin
ri_icmp_len <= i_icmp_len ;
ri_icmp_data <= i_icmp_data ;
ri_icmp_last <= i_icmp_last ;
ri_icmp_valid <= i_icmp_valid;
end
end
//开始计数
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst)
r_icmp_cnt <= 'd0;
else if(ri_icmp_valid)
r_icmp_cnt <= r_icmp_cnt + 1;
else
r_icmp_cnt <= 'd0;
end
//存下icmp类型
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst)
r_type <= 'd0;
else if(ri_icmp_valid && r_icmp_cnt == 0)
r_type <= ri_icmp_data;
else
r_type <= r_type;
end
//ICMP帧的 序号
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst)
ro_trig_seq <= 'd0;
else if(r_icmp_cnt >=6 && r_icmp_cnt <= 7)
ro_trig_seq <= {ro_trig_seq[7 :0],ri_icmp_data};
else
ro_trig_seq <= ro_trig_seq;
end
//类型为8 计数8个 拉高序号的回复信号
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst)
ro_trig_reply <= 'd0;
else if(r_icmp_cnt == 7 && r_type == 8)
ro_trig_reply <= 'd1;
else
ro_trig_reply <= 'd0;
end
endmodule
5.2 ICMP发送模块
c
module ICMP_tx(
input i_clk ,
input i_rst ,
input i_trig_reply ,
input [15:0] i_trig_seq ,
output [15:0] o_icmp_len ,
output [7 :0] o_icmp_data ,
output o_icmp_last ,
output o_icmp_valid
);
/***************function**************/
/***************parameter*************/
localparam P_LEN = 40 ;
/***************port******************/
/***************mechine***************/
/***************reg*******************/
reg ri_trig_reply ;
reg [15:0] ri_trig_seq ;
reg [15:0] ro_icmp_len ;
reg [7 :0] ro_icmp_data ;
reg ro_icmp_last ;
reg ro_icmp_valid ;
reg [15:0] r_icmp_cnt ;
reg [31:0] r_icmp_check ;
reg [7 :0] r_check_cnt ;
/***************wire******************/
/***************component*************/
/***************assign****************/
assign o_icmp_len = ro_icmp_len ;
assign o_icmp_data = ro_icmp_data ;
assign o_icmp_last = ro_icmp_last ;
assign o_icmp_valid = ro_icmp_valid;
/***************always****************/
//序号值 和 信号 打一拍
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst) begin
ri_trig_reply <= 'd0;
ri_trig_seq <= 'd0;
end else begin
ri_trig_reply <= i_trig_reply;
ri_trig_seq <= i_trig_seq;
end
end
//r_check_cnt 在 ri_trig_reply拉高后 +1
//r_icmp_cnt 计数完,r_check_cnt清空
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst)
r_check_cnt <= 'd0;
else if(r_icmp_cnt == P_LEN - 1)
r_check_cnt <= 'd0;
else if(r_check_cnt == 3)
r_check_cnt <= r_check_cnt + 1;
else if(ri_trig_reply | r_check_cnt)
r_check_cnt <= r_check_cnt + 1;
else
r_check_cnt <= r_check_cnt;
end
//ICMP的校验和 和IP层的首部校验和一样
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst)
r_icmp_check <= 'd0;
else if(r_check_cnt == 0)
r_icmp_check <= 16'h0001 + ri_trig_seq;
else if(r_check_cnt == 1)
r_icmp_check <= r_icmp_check[31:16] + r_icmp_check[15:0];
else if(r_check_cnt == 2)
r_icmp_check <= r_icmp_check[31:16] + r_icmp_check[15:0];
else if(r_check_cnt == 3)
r_icmp_check <= ~r_icmp_check;
else
r_icmp_check <= r_icmp_check;
end
//校验完成后 开始组帧计数
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst)
r_icmp_cnt <= 'd0;
else if(r_icmp_cnt == P_LEN - 1)
r_icmp_cnt <= 'd0;
else if(r_check_cnt == 3 || r_icmp_cnt)
r_icmp_cnt <= r_icmp_cnt + 1;
else
r_icmp_cnt <= r_icmp_cnt;
end
//ICMP的长度 输出
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst)
ro_icmp_len <= 'd0;
else
ro_icmp_len <= P_LEN;
end
//校验完成输出 ICMP帧,使能拉高
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst)
ro_icmp_valid <= 'd0;
else if(r_icmp_cnt == P_LEN - 1)
ro_icmp_valid <= 'd0;
else if(r_check_cnt == 3)
ro_icmp_valid <= 'd1;
else
ro_icmp_valid <= ro_icmp_valid;
end
//输出结束信号
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst)
ro_icmp_last <= 'd0;
else if(r_icmp_cnt == P_LEN - 2)
ro_icmp_last <= 'd1;
else
ro_icmp_last <= 'd0;
end
//组帧
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst)
ro_icmp_data <= 'd0;
else case(r_icmp_cnt)
0 :ro_icmp_data <= 'd0;
1 :ro_icmp_data <= 'd0;
2 :ro_icmp_data <= r_icmp_check[15:8];
3 :ro_icmp_data <= r_icmp_check[7 :0];
4 :ro_icmp_data <= 8'h00;
5 :ro_icmp_data <= 8'h01;
6 :ro_icmp_data <= ri_trig_seq[15:8];
7 :ro_icmp_data <= ri_trig_seq[7 :0];
default :ro_icmp_data <= 'd0;
endcase
end
endmodule
6.1 ARP接收模块
c
module ARP_rx#(
parameter P_TARGET_IP = {8'd192,8'd168,8'd1,8'd1},
parameter P_SOURCE_MAC = {8'h00,8'h00,8'h00,8'h00,8'h00,8'h00},
parameter P_SOURCE_IP = {8'd192,8'd168,8'd1,8'd2}
)(
input i_clk ,
input i_rst ,
input [31:0] i_source_ip ,
input i_s_ip_valid ,
/*--------info port--------*/
output [47:0] o_target_mac ,
output [31:0] o_target_ip ,
output o_target_valid ,
output o_tirg_reply ,
/*--------MAC port--------*/
input [7 :0] i_mac_data ,
input i_mac_last ,
input i_mac_valid
);
/***************function**************/
/***************parameter*************/
/***************port******************/
/***************mechine***************/
/***************reg*******************/
reg [47:0] ro_target_mac ;
reg [31:0] ro_target_ip ;
reg ro_target_valid ;
reg [7 :0] ri_mac_data ;
reg [7 :0] ri_mac_data_1d ;
reg ri_mac_last ;
reg ri_mac_valid ;
reg [15:0] r_mac_cnt ;
reg [15:0] r_arp_op ;
reg ro_tirg_reply ;
reg [31:0] ri_source_ip ;
/***************wire******************/
/***************component*************/
/***************assign****************/
assign o_target_mac = ro_target_mac ;
assign o_target_ip = ro_target_ip ;
assign o_tirg_reply = ro_tirg_reply ;
assign o_target_valid = ro_target_valid;
/***************always****************/
//打拍
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst) begin
ri_mac_data <= 'd0;
ri_mac_last <= 'd0;
ri_mac_valid <= 'd0;
ri_mac_data_1d <= 'd0;
end else begin
ri_mac_data <= i_mac_data ;
ri_mac_last <= i_mac_last ;
ri_mac_valid <= i_mac_valid;
ri_mac_data_1d <= ri_mac_data;
end
end
//源ip 锁存
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst)
ri_source_ip <= P_SOURCE_IP;
else if(i_s_ip_valid)
ri_source_ip <= i_source_ip;
else
ri_source_ip <= ri_source_ip;
end
//mac计数器
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst)
r_mac_cnt <= 'd0;
else if(ri_mac_valid)
r_mac_cnt <= r_mac_cnt + 1;
else
r_mac_cnt <= 'd0;
end
//获得ARP的操作类型
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst)
r_arp_op <= 'd0;
else if(r_mac_cnt >= 6 && r_mac_cnt <= 7)
r_arp_op <= {r_arp_op[7 :0],ri_mac_data};
else
r_arp_op <= r_arp_op;
end
//获得目的mac
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst)
ro_target_mac <= 'd0;
else if(r_mac_cnt >= 8 && r_mac_cnt <= 13 && (r_arp_op == 1 || r_arp_op == 2))
ro_target_mac <= {ro_target_mac[39:0],ri_mac_data};
else
ro_target_mac <= ro_target_mac;
end
//获得目的ip
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst)
ro_target_ip <= 'd0;
else if(r_mac_cnt >= 14 && r_mac_cnt <= 17 && (r_arp_op == 1 || r_arp_op == 2))
ro_target_ip <= {ro_target_ip[23:0],ri_mac_data};
else
ro_target_ip <= ro_target_ip;
end
//计数到17 拉高有效信号
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst)
ro_target_valid <= 'd0;
else if(r_mac_cnt == 17)
ro_target_valid <= 'd1;
else
ro_target_valid <= 'd0;
end
//计数到18 类型为1 请求
//回复信号触发信号 拉高
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst)
ro_tirg_reply <= 'd0;
else if(r_mac_cnt == 18 && r_arp_op == 1)
ro_tirg_reply <= 'd1;
else
ro_tirg_reply <= 'd0;
end
endmodule
6.2 ARP发送模块
c
module ARP_tx#(
parameter P_TARGET_IP = {8'd192,8'd168,8'd1,8'd1},
parameter P_SOURCE_MAC = {8'h00,8'h00,8'h00,8'h00,8'h00,8'h00},
parameter P_SOURCE_IP = {8'd192,8'd168,8'd1,8'd2}
)(
input i_clk ,
input i_rst ,
input [31:0] i_target_ip ,
input i_target_valid ,
input [47:0] i_source_mac ,
input i_s_mac_valid ,
input [31:0] i_source_ip ,
input i_s_ip_valid ,
input [47:0] i_reply_mac ,
output [31:0] o_seek_ip ,
output o_seek_valid ,
input i_trig_reply ,
input i_active_send ,
output [7 :0] o_mac_data ,
output o_mac_last ,
output o_mac_valid
);
/***************function**************/
/***************parameter*************/
localparam P_LEN = 46 ;
/***************port******************/
/***************mechine***************/
/***************reg*******************/
reg [31:0] r_target_ip ;
reg ri_trig_reply ;
reg ri_active_send ;
reg [7 :0] ro_mac_data ;
reg ro_mac_last ;
reg ro_mac_valid ;
reg [15:0] r_mac_cnt ;
reg [15:0] r_arp_op ;
reg [47:0] ri_source_mac ;
reg [31:0] ri_source_ip ;
reg [31:0] ro_seek_ip ;
reg ro_seek_valid ;
reg [47:0] ri_reply_mac ;
reg [15:0] r_arp_cnt ;
/***************wire******************/
wire w_act ;
/***************component*************/
/***************assign****************/
assign o_mac_data = ro_mac_data ;
assign o_mac_last = ro_mac_last ;
assign o_mac_valid = ro_mac_valid ;
assign o_seek_ip = ro_seek_ip ;
assign o_seek_valid = ro_seek_valid ;
assign w_act = r_arp_cnt == 10;
/***************always****************/
//主动ARP和被动ARP 触发有效
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst)
ro_seek_valid <= 'd0;
else if(i_trig_reply | i_active_send)
ro_seek_valid <= 'd1;
else
ro_seek_valid <= 'd0;
end
//输出 源ip
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst)
ro_seek_ip <= 'd0;
else
ro_seek_ip <= ri_source_ip;
end
//输入目的有效 获得目的ip
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst)
r_target_ip <= P_TARGET_IP;
else if(i_target_valid)
r_target_ip <= i_target_ip;
else
r_target_ip <= r_target_ip;
end
//输入mac有效,获得源mac
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst)
ri_source_mac <= P_SOURCE_MAC;
else if(i_s_mac_valid)
ri_source_mac <= i_source_mac;
else
ri_source_mac <= ri_source_mac;
end
//输入ip有效,获得源ip
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst)
ri_source_ip <= P_SOURCE_IP;
else if(i_s_ip_valid)
ri_source_ip <= i_source_ip;
else
ri_source_ip <= ri_source_ip;
end
// 被动触发 和主动触发信号打拍
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst) begin
ri_trig_reply <= 'd0;
ri_active_send <= 'd0;
end else begin
ri_trig_reply <= i_trig_reply ;
ri_active_send <= i_active_send | w_act;
end
end
//r_arp_cnt计数器 0 到 11
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst)
r_arp_cnt <= 'd0;
else if(r_arp_cnt < 11)
r_arp_cnt <= r_arp_cnt + 1;
else
r_arp_cnt <= r_arp_cnt;
end
//打拍后的触发信号,控制开始mac帧计数
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst)
r_mac_cnt <= 'd0;
else if(r_mac_cnt == P_LEN - 1)
r_mac_cnt <= 'd0;
else if(ri_trig_reply || ri_active_send || r_mac_cnt)
r_mac_cnt <= r_mac_cnt + 1;
else
r_mac_cnt <= r_mac_cnt;
end
//打拍后的触发信号,控制回复类型值
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst)
r_arp_op <= 'd0;
else if(ri_trig_reply)
r_arp_op <= 'd2;
else if(ri_active_send)
r_arp_op <= 'd1;
else
r_arp_op <= r_arp_op;
end
//得到mac帧 用于回复
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst)
ri_reply_mac <= 'd0;
else
ri_reply_mac <= i_reply_mac;
end
//组帧输出
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst)
ro_mac_data <= 'd0;
else case(r_mac_cnt)
0 :ro_mac_data <= 'd0;
1 :ro_mac_data <= 'd1;
2 :ro_mac_data <= 8'h08;
3 :ro_mac_data <= 8'h00;
4 :ro_mac_data <= 'd6;
5 :ro_mac_data <= 'd4;
6 :ro_mac_data <= r_arp_op[15:8];
7 :ro_mac_data <= r_arp_op[7 :0];
8 :ro_mac_data <= ri_source_mac[47:40];
9 :ro_mac_data <= ri_source_mac[39:32];
10 :ro_mac_data <= ri_source_mac[31:24];
11 :ro_mac_data <= ri_source_mac[23:16];
12 :ro_mac_data <= ri_source_mac[15: 8];
13 :ro_mac_data <= ri_source_mac[7 : 0];
14 :ro_mac_data <= ri_source_ip[31:24];
15 :ro_mac_data <= ri_source_ip[23:16];
16 :ro_mac_data <= ri_source_ip[15: 8];
17 :ro_mac_data <= ri_source_ip[7 : 0];
18 :ro_mac_data <= r_arp_op == 2 ? ri_reply_mac[47:40] : 8'h00;
19 :ro_mac_data <= r_arp_op == 2 ? ri_reply_mac[39:32] : 8'h00;
20 :ro_mac_data <= r_arp_op == 2 ? ri_reply_mac[31:24] : 8'h00;
21 :ro_mac_data <= r_arp_op == 2 ? ri_reply_mac[23:16] : 8'h00;
22 :ro_mac_data <= r_arp_op == 2 ? ri_reply_mac[15: 8] : 8'h00;
23 :ro_mac_data <= r_arp_op == 2 ? ri_reply_mac[7 : 0] : 8'h00;
24 :ro_mac_data <= r_target_ip[31:24];
25 :ro_mac_data <= r_target_ip[23:16];
26 :ro_mac_data <= r_target_ip[15: 8];
27 :ro_mac_data <= r_target_ip[7 : 0];
default :ro_mac_data <= 'd0;
endcase
end
//到长度就拉低有效信号
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst)
ro_mac_valid <= 'd0;
else if(r_mac_cnt == P_LEN - 1)
ro_mac_valid <= 'd0;
else if(ri_trig_reply || ri_active_send )
ro_mac_valid <= 'd1;
else
ro_mac_valid <= ro_mac_valid;
end
//产生last信号
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst)
ro_mac_last <= 'd0;
else if(r_mac_cnt == P_LEN - 2)
ro_mac_last <= 'd1;
else
ro_mac_last <= 'd0;
end
endmodule
6.3 ARP表模块
c
module ARP_Table(
input i_clk ,
input i_rst ,
input [31:0] i_seek_ip ,
input i_seek_valid ,
input [31:0] i_updata_ip ,
input [47:0] i_updata_mac ,
input i_updata_valid ,
output [47:0] o_active_mac ,
output o_active_valid
);
/***************function**************/
/***************parameter*************/
localparam P_ST_IDLE = 0 ,
P_ST_SEEK = 1 ,
P_ST_UPDATA_S = 2 ,
P_ST_UPDATA = 3 ,
P_ST_MAC = 4 ;
/***************port******************/
/***************mechine***************/
reg [7 :0] r_st_current ;
reg [7 :0] r_st_next ;
/***************reg*******************/
reg [31:0] r_seek_ip ;
reg [31:0] r_updata_ip ;
reg [47:0] r_updata_mac ;
reg [47:0] ro_active_mac ;
reg ro_active_valid ;
reg ri_seek_valid ;
reg ri_updata_valid ;
reg r_ram_ip_en ;
reg r_ram_ip_we ;
reg [2 :0] r_ram_ip_addr ;
reg r_ram_ip_dv ;
reg r_ram_mac_en ;
reg r_ram_mac_we ;
reg [2 :0] r_ram_mac_addr ;
reg r_ram_mac_dv ;
reg r_ip_access ;
reg [2 :0] r_access_addr ;
reg r_ram_ip_end ;
reg r_ram_ip_end_1d ;
reg r_updata_acc ;
reg [2 :0] r_up_data_addr ;
/***************wire******************/
wire [31:0] w_ram_ip_dout ;
wire [47:0] w_ram_mac_dout ;
wire w_seek_v_pos ;
wire w_seek_v_neg ;
wire w_updata_v_pos ;
wire w_updata_v_neg ;
wire r_ram_ip_end_neg;
/***************component*************/
RAM_IP RAM_IP_U0 (
.clka (i_clk ),
.ena (r_ram_ip_en ),
.wea (r_ram_ip_we ),
.addra (r_ram_ip_addr ),
.dina (r_updata_ip ),
.douta (w_ram_ip_dout )
);
RAM_MAC RAM_MAC_U0 (
.clka (i_clk ),
.ena (r_ram_mac_en ),
.wea (r_ram_mac_we ),
.addra (r_ram_mac_addr ),
.dina (r_updata_mac ),
.douta (w_ram_mac_dout )
);
/***************assign****************/
assign o_active_mac = ro_active_mac ;
assign o_active_valid = ro_active_valid ;
assign w_seek_v_pos = i_seek_valid & !ri_seek_valid;
assign w_seek_v_neg = !i_seek_valid & ri_seek_valid;
assign w_updata_v_pos = i_updata_valid & !ri_updata_valid;
assign w_updata_v_neg = !i_updata_valid & ri_updata_valid;
assign r_ram_ip_end_neg = r_ram_ip_end & !r_ram_ip_end_1d;
/***************always****************/
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst)
r_st_current <= P_ST_IDLE;
else
r_st_current <= r_st_next;
end
always@(*)
begin
case(r_st_current)
P_ST_IDLE :r_st_next = w_seek_v_pos ? P_ST_SEEK :
i_updata_valid ? P_ST_UPDATA_S : P_ST_IDLE;
P_ST_SEEK :r_st_next = r_ip_access || (r_ram_ip_end_neg && !r_ip_access)? P_ST_MAC : P_ST_SEEK;
P_ST_UPDATA_S :r_st_next = r_updata_acc ? P_ST_IDLE :
(r_ram_ip_end_neg && !r_updata_acc) ? P_ST_UPDATA : P_ST_UPDATA_S;
P_ST_UPDATA :r_st_next = P_ST_IDLE;
P_ST_MAC :r_st_next = P_ST_IDLE;
default :r_st_next = P_ST_IDLE;
endcase
end
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst)
r_seek_ip <= 'd0;
else if(i_seek_valid)
r_seek_ip <= i_seek_ip;
else
r_seek_ip <= r_seek_ip;
end
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst) begin
r_updata_ip <= 'd0;
r_updata_mac <= 'd0;
end else if(i_updata_valid) begin
r_updata_ip <= i_updata_ip ;
r_updata_mac <= i_updata_mac;
end else begin
r_updata_ip <= r_updata_ip ;
r_updata_mac <= r_updata_mac;
end
end
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst) begin
ri_seek_valid <= 'd0;
ri_updata_valid <= 'd0;
end else begin
ri_seek_valid <= i_seek_valid ;
ri_updata_valid <= i_updata_valid;
end
end
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst) begin
r_ram_ip_en <= 'd0;
r_ram_ip_we <= 'd0;
r_ram_ip_addr <= 'd0;
end else if(r_st_current == P_ST_SEEK && !r_ram_ip_end) begin
r_ram_ip_en <= 'd1;
r_ram_ip_we <= 'd0;
if(r_ram_ip_en) r_ram_ip_addr <= r_ram_ip_addr + 1;
else r_ram_ip_addr <= 'd0;
end else if(r_st_current == P_ST_UPDATA_S && !r_ram_ip_end) begin
r_ram_ip_en <= 'd1;
r_ram_ip_we <= 'd0;
if(r_ram_ip_en) r_ram_ip_addr <= r_ram_ip_addr + 1;
else r_ram_ip_addr <= 'd0;
end else if(r_st_current == P_ST_UPDATA) begin
r_ram_ip_en <= 'd1;
r_ram_ip_we <= 'd1;
r_ram_ip_addr <= r_up_data_addr;
end else begin
r_ram_ip_en <= 'd0;
r_ram_ip_we <= 'd0;
r_ram_ip_addr <= 'd0;
end
end
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst) begin
r_ram_mac_en <= 'd0;
r_ram_mac_we <= 'd0;
r_ram_mac_addr <= 'd0;
end else if(r_st_current == P_ST_UPDATA_S && !r_ram_ip_end) begin
r_ram_mac_en <= 'd1;
r_ram_mac_we <= 'd0;
r_ram_mac_addr <= r_ram_mac_addr + 1;
end else if(r_st_current == P_ST_UPDATA) begin
r_ram_mac_en <= 'd1;
r_ram_mac_we <= 'd1;
r_ram_mac_addr <= r_up_data_addr;
end else if(r_ram_ip_dv && w_ram_ip_dout == r_seek_ip) begin
r_ram_mac_en <= 'd1;
r_ram_mac_we <= 'd0;
r_ram_mac_addr <= r_access_addr;
end else begin
r_ram_mac_en <= 'd0;
r_ram_mac_we <= 'd0;
r_ram_mac_addr <= 'd0;
end
end
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst)
r_ram_ip_end <= 'd0;
else if(r_st_current == P_ST_IDLE)
r_ram_ip_end <= 'd0;
else if(r_st_current == P_ST_SEEK && r_ram_ip_addr == 7)
r_ram_ip_end <= 'd1;
else if(r_st_current == P_ST_UPDATA_S && r_ram_ip_addr == 7)
r_ram_ip_end <= 'd1;
else
r_ram_ip_end <= r_ram_ip_end;
end
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst)
r_ram_ip_end_1d <= 'd0;
else
r_ram_ip_end_1d <= r_ram_ip_end;
end
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst)
r_ram_ip_dv <= 'd0;
else if(r_ram_ip_en && !r_ram_ip_we && !r_ip_access)
r_ram_ip_dv <= 'd1;
else
r_ram_ip_dv <= 'd0;
end
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst)
r_ip_access <= 'd0;
else if(r_st_current == P_ST_IDLE)
r_ip_access <= 'd0;
else if(r_ram_ip_dv && w_ram_ip_dout == r_seek_ip)
r_ip_access <= 'd1;
else
r_ip_access <= r_ip_access;
end
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst)
r_access_addr <= 'd0;
else if(r_st_current == P_ST_IDLE)
r_access_addr <= 'd0;
else if(r_ram_ip_dv && !r_ip_access)
r_access_addr <= r_access_addr + 1;
else
r_access_addr <= r_access_addr;
end
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst)
r_updata_acc <= 'd0;
else if(r_ram_ip_dv && w_ram_ip_dout == r_updata_ip && w_ram_mac_dout == r_updata_mac)
r_updata_acc <= 'd1;
else
r_updata_acc <= 'd0;
end
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst)
r_up_data_addr <= 'd0;
else if(r_st_current == P_ST_UPDATA)
r_up_data_addr <= r_up_data_addr + 1;
else
r_up_data_addr <= r_up_data_addr;
end
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst)
ro_active_mac <= 48'd0;
else if(r_st_current == P_ST_MAC && r_ip_access)
ro_active_mac <= w_ram_mac_dout;
else
ro_active_mac <= 48'hffffffffffff;
end
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst)
ro_active_valid <= 'd0;
else if(r_st_current == P_ST_MAC)
ro_active_valid <= 'd1;
else
ro_active_valid <= 'd0;
end
endmodule
7 CRC数据对比模块
要双端口ram读写缓存帧的数据和FIFO配合存储帧长度和类型
c
module CRC_Data_Pro(
input i_clk ,
input i_rst ,
input [15:0] i_per_type ,
input [7 :0] i_per_data ,
input i_per_last ,
input i_per_valid ,
input i_per_crc_error ,
input i_per_crc_valid ,
output [15:0] o_post_type ,
output [7 :0] o_post_data ,
output o_post_last ,
output o_post_valid
);
/***************function**************/
/***************parameter*************/
localparam P_FRAME_GAP = 12 ;
/***************port******************/
/***************mechine***************/
/***************reg*******************/
reg [15:0] ri_per_type ;
reg [7 :0] ri_per_data ;
reg ri_per_last ;
reg ri_per_valid ;
reg ri_per_valid_1d ;
reg ri_per_crc_error ;
reg ri_per_crc_valid ;
reg [7 :0] ro_post_data ;
reg ro_post_last ;
reg ro_post_valid ;
reg r_ram_en_A ;
reg r_ram_we_A ;
reg [11:0] r_ram_addr_A ;
reg [7 :0] r_ram_din_A ;
reg r_ram_en_B ;
reg r_ram_en_B_1d ;
reg r_ram_we_B ;
reg [11:0] r_ram_addr_B ;
reg [10:0] r_data_len ;
reg [10:0] r_data_len_o ;
reg r_fifo_rd_en ;
reg r_fifo_rd_en_1d ;
reg r_fifo_wr_en ;
reg r_out_run ;
reg r_out_run_1d ;
reg [10:0] r_fifo_dout ;
reg [15:0] r_gap_cnt ;
reg [15:0] ro_post_type ;
reg ri_per_last_1d ;
/***************wire******************/
wire [7 :0] w_ram_dout_B ;
wire [10:0] w_fifo_dout ;
wire w_fifo_empty ;
wire w_fifo_full ;
wire [15:0] w_fifo_type ;
/***************component*************/
RAM_8x1500_TrueDual RAM_8x1500_TrueDual_u0 (//修改为8X3000
.clka (i_clk ),
.ena (r_ram_en_A ),
.wea (r_ram_we_A ),
.addra (r_ram_addr_A ),
.dina (r_ram_din_A ),
.douta (),
.clkb (i_clk ),
.enb (r_ram_en_B ),
.web (r_ram_we_B ),
.addrb (r_ram_addr_B ),
.dinb (0 ),
.doutb (w_ram_dout_B )
);
FIFO_11X64 FIFO_11X64_U0 (
.clk (i_clk ),
.din (r_data_len ),
.wr_en (r_fifo_wr_en ),
.rd_en (r_fifo_rd_en ),
.dout (w_fifo_dout ),
.full (w_fifo_full ),
.empty (w_fifo_empty )
);
FIFO_16X64 FIFO_16X64_U1 (
.clk (i_clk ),
.din (ri_per_type ),
.wr_en (r_fifo_wr_en ),
.rd_en (r_fifo_rd_en ),
.dout (w_fifo_type ),
.full (),
.empty ()
);
/***************assign****************/
assign o_post_data = ro_post_data ;
assign o_post_last = ro_post_last ;
assign o_post_valid = ro_post_valid;
assign o_post_type = ro_post_type;
/***************always****************/
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst) begin
ri_per_data <= 'd0;
ri_per_last <= 'd0;
ri_per_valid <= 'd0;
ri_per_type <= 'd0;
ri_per_crc_error <= 'd0;
ri_per_crc_valid <= 'd0;
end else begin
ri_per_data <= i_per_data ;
ri_per_last <= i_per_last ;
ri_per_valid <= i_per_valid ;
ri_per_type <= i_per_type ;
ri_per_crc_error <= i_per_crc_error;
ri_per_crc_valid <= i_per_crc_valid;
end
end
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst) begin
r_ram_en_A <= 'd0;
r_ram_we_A <= 'd0;
r_ram_din_A <= 'd0;
end else if(ri_per_valid) begin
r_ram_en_A <= 'd1;
r_ram_we_A <= 'd1;
r_ram_din_A <= ri_per_data;
end else begin
r_ram_en_A <= 'd0;
r_ram_we_A <= 'd0;
r_ram_din_A <= 'd0;
end
end
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst)
ri_per_valid_1d <= 'd0;
else
ri_per_valid_1d <= ri_per_valid;
end
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst)
r_ram_addr_A <= 'd0;
else if(ri_per_crc_valid && ri_per_crc_error)
r_ram_addr_A <= r_ram_addr_A - r_data_len;
else if(r_ram_addr_A == 2999)
r_ram_addr_A <= 'd0;
else if(ri_per_valid && !ri_per_valid_1d)
r_ram_addr_A <= r_ram_addr_A;
else if(ri_per_valid | ri_per_valid_1d)
r_ram_addr_A <= r_ram_addr_A + 1;
else
r_ram_addr_A <= r_ram_addr_A;
end
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst)
ri_per_last_1d <= 'd0;
else
ri_per_last_1d <= ri_per_last;
end
// always@(posedge i_clk,posedge i_rst)
// begin
// if(i_rst)
// r_data_len <= 'd0;
// else if(ri_per_last_1d)
// r_data_len <= r_ram_addr_A;
// else
// r_data_len <= r_data_len;
// end
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst)
r_data_len <= 'd0;
else if(r_fifo_wr_en)
r_data_len <= 'd0;
else if(ri_per_valid)
r_data_len <= r_data_len + 1;
else
r_data_len <= r_data_len;
end
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst)
r_fifo_wr_en <= 'd0;
else if(ri_per_crc_valid && !ri_per_crc_error && !r_fifo_wr_en)
r_fifo_wr_en <= 'd1;
else
r_fifo_wr_en <= 'd0;
end
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst)
r_fifo_rd_en <= 'd0;
else if(!w_fifo_empty && !r_out_run && !r_fifo_rd_en && r_gap_cnt == P_FRAME_GAP - 4)
r_fifo_rd_en <= 'd1;
else
r_fifo_rd_en <= 'd0;
end
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst)
r_fifo_rd_en_1d <= 'd0;
else
r_fifo_rd_en_1d <= r_fifo_rd_en;
end
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst)
r_fifo_dout <= 'd0;
else if(r_fifo_rd_en_1d)
r_fifo_dout <= w_fifo_dout;
else
r_fifo_dout <= r_fifo_dout;
end
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst)
r_out_run <= 'd0;
else if(r_data_len_o == r_fifo_dout - 1)
r_out_run <= 'd0;
else if(!r_fifo_rd_en && r_fifo_rd_en_1d)
r_out_run <= 'd1;
else
r_out_run <= r_out_run;
end
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst)
r_data_len_o <= 'd0;
else if(r_data_len_o == r_fifo_dout - 1)
r_data_len_o <= 'd0;
else if(r_out_run)
r_data_len_o <= r_data_len_o + 1;
else
r_data_len_o <= r_data_len_o;
end
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst)
r_out_run_1d <= 'd0;
else
r_out_run_1d <= r_out_run;
end
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst) begin
r_ram_en_B <= 'd0;
r_ram_we_B <= 'd0;
end else if(r_out_run && !r_out_run_1d) begin
r_ram_en_B <= 'd1;
r_ram_we_B <= 'd0;
end else if(r_out_run) begin
r_ram_en_B <= 'd1;
r_ram_we_B <= 'd0;
end else begin
r_ram_en_B <= 'd0;
r_ram_we_B <= 'd0;
end
end
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst)
r_ram_addr_B <= 'd0;
else if(r_ram_addr_B == 2999)
r_ram_addr_B <= 'd0;
else if(r_out_run && !r_out_run_1d)
r_ram_addr_B <= r_ram_addr_B;
else if(r_out_run | r_out_run_1d)
r_ram_addr_B <= r_ram_addr_B + 1;
else
r_ram_addr_B <= r_ram_addr_B;
end
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst)
ro_post_data <= 'd0;
else if(r_ram_en_B_1d)
ro_post_data <= w_ram_dout_B;
else
ro_post_data <= 'd0;
end
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst)
ro_post_type <= 'd0;
else if(r_fifo_rd_en_1d)
ro_post_type <= w_fifo_type;
else
ro_post_type <= ro_post_type;
end
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst)
r_ram_en_B_1d <= 'd0;
else
r_ram_en_B_1d <= r_ram_en_B;
end
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst)
ro_post_valid <= 'd0;
else
ro_post_valid <= r_ram_en_B_1d;
end
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst)
ro_post_last <= 'd0;
else if(!r_ram_en_B && r_ram_en_B_1d)
ro_post_last <= 'd1;
else
ro_post_last <= 'd0;
end
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst)
r_gap_cnt <= 'd1;
else if(r_fifo_rd_en)
r_gap_cnt <= 'd0;
else if(r_gap_cnt == P_FRAME_GAP - 4)
r_gap_cnt <= r_gap_cnt;
else if(ro_post_last | r_gap_cnt)
r_gap_cnt <= r_gap_cnt + 1;
else
r_gap_cnt <= r_gap_cnt;
end
endmodule
8 MAC下ARP和IP数据分流模块
类型是0800就是IP 0806就是ARP,进行分流操作
c
module mac_arp_ip_mux(
input i_clk ,
input i_rst ,
input [15:0] i_type ,
input [7 :0] i_data ,
input i_last ,
input i_valid ,
output [7 :0] o_ip_data ,
output o_ip_last ,
output o_ip_valid ,
output [7 :0] o_arp_data ,
output o_arp_last ,
output o_arp_valid
);
reg [7 :0] ro_ip_data ;
reg ro_ip_last ;
reg ro_ip_valid ;
reg [7 :0] ro_arp_data ;
reg ro_arp_last ;
reg ro_arp_valid ;
assign o_ip_data = ro_ip_data ;
assign o_ip_last = ro_ip_last ;
assign o_ip_valid = ro_ip_valid ;
assign o_arp_data = ro_arp_data ;
assign o_arp_last = ro_arp_last ;
assign o_arp_valid = ro_arp_valid ;
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst) begin
ro_ip_data <= 'd0;
ro_ip_last <= 'd0;
ro_ip_valid <= 'd0;
end else if(i_type == 16'h0800) begin
ro_ip_data <= i_data ;
ro_ip_last <= i_last ;
ro_ip_valid <= i_valid;
end else begin
ro_ip_data <= 'd0;
ro_ip_last <= 'd0;
ro_ip_valid <= 'd0;
end
end
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst) begin
ro_arp_data <= 'd0;
ro_arp_last <= 'd0;
ro_arp_valid <= 'd0;
end else if(i_type == 16'h0806) begin
ro_arp_data <= i_data ;
ro_arp_last <= i_last ;
ro_arp_valid <= i_valid;
end else begin
ro_arp_data <= 'd0;
ro_arp_last <= 'd0;
ro_arp_valid <= 'd0;
end
end
endmodule
9 数据流仲裁模块
两个数据流都加个FIFO,以帧为单位,先输出A,A输出完成后再输出B。还要进行流控:要切换通道输出时,要先把现在这个通道的FIFO数据输出完,才能来新通道的输入,保证多次操作之后FIFO不会溢出。
c
module Data_2to1(
input i_clk ,
input i_rst ,
input [15:0] i_type_A ,
input [15:0] i_len_A ,
input [7 :0] i_data_A ,
input i_last_A ,
input i_valid_A ,
output o_next_frame_stop ,
input [15:0] i_type_B ,
input [15:0] i_len_B ,
input [7 :0] i_data_B ,
input i_last_B ,
input i_valid_B ,
output [15:0] o_type ,
output [15:0] o_len ,
output [7 :0] o_data ,
output o_last ,
output o_valid
);
/***************function**************/
/***************parameter*************/
/***************port******************/
/***************mechine***************/
/***************reg*******************/
reg [15:0] ri_type_A ;
reg [15:0] ri_len_A ;
reg [7 :0] ri_data_A ;
reg ri_last_A ;
reg ri_valid_A ;
reg ri_valid_A_1d ;
reg [15:0] ri_type_B ;
reg [15:0] ri_len_B ;
reg [7 :0] ri_data_B ;
reg ri_last_B ;
reg ri_valid_B ;
reg ri_valid_B_1d ;
reg [7 :0] ro_data ;
reg ro_last ;
reg ro_valid ;
reg r_fifo_A_rden ;
reg r_fifo_B_rden ;
reg r_fifo_A_rden_1d;
reg r_fifo_B_rden_1d;
reg [1 :0] r_fifo_rd ;
reg [1:0] r_arbiter ;
reg [15:0] r_rd_cnt ;
reg r_rd_en ;
reg ro_next_frame_stop ;
reg [15:0] ro_type ;
reg [15:0] ro_len ;
reg r_rden_A_pos ;
reg r_rden_B_pos ;
reg [7 :0] r_cnt ;
/***************wire******************/
wire [7 :0] w_fifo_A_dout ;
wire w_fifo_A_full ;
wire w_fifo_A_empty ;
wire [7 :0] w_fifo_B_dout ;
wire w_fifo_B_full ;
wire w_fifo_B_empty ;
wire w_rd_en ;
wire w_valid_A_pos ;
wire w_valid_B_pos ;
wire w_rden_A_pos ;
wire w_rden_B_pos ;
wire [31:0] w_A_type_len ;
wire [31:0] w_B_type_len ;
/***************component*************/
FIFO_8X256 FIFO_8X256_U0_A (
.clk (i_clk ),
.din (ri_data_A ),
.wr_en (ri_valid_A ),
.rd_en (r_fifo_A_rden ),
.dout (w_fifo_A_dout ),
.full (w_fifo_A_full ),
.empty (w_fifo_A_empty )
);
FIFO_32X16 FIFO_32X16_A (
.clk (i_clk ),
.din ({ri_type_A,ri_len_A} ),
.wr_en (w_valid_A_pos ),
.rd_en (w_rden_A_pos ),
.dout (w_A_type_len ),
.full (),
.empty ()
);
FIFO_8X256 FIFO_8X256_U0_B (
.clk (i_clk ),
.din (ri_data_B ),
.wr_en (ri_valid_B ),
.rd_en (r_fifo_B_rden ),
.dout (w_fifo_B_dout ),
.full (w_fifo_B_full ),
.empty (w_fifo_B_empty )
);
FIFO_32X16 FIFO_32X16_B (
.clk (i_clk ),
.din ({ri_type_B,ri_len_B} ),
.wr_en (w_valid_B_pos ),
.rd_en (w_rden_B_pos ),
.dout (w_B_type_len ),
.full (),
.empty ()
);
/***************assign****************/
assign o_data = ro_data ;
assign o_last = ro_last ;
assign o_valid = ro_valid ;
assign w_rd_en = r_fifo_A_rden | r_fifo_B_rden;
assign o_next_frame_stop = ro_next_frame_stop;
assign w_valid_A_pos = ri_valid_A & !ri_valid_A_1d;
assign w_valid_B_pos = ri_valid_B & !ri_valid_B_1d;
assign w_rden_A_pos = r_fifo_A_rden & !r_fifo_A_rden_1d;
assign w_rden_B_pos = r_fifo_B_rden & !r_fifo_B_rden_1d;
assign o_type = ro_type;
assign o_len = ro_len ;
/***************always****************/
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst) begin
ri_type_A <= 'd0;
ri_len_A <= 'd0;
ri_data_A <= 'd0;
ri_last_A <= 'd0;
ri_valid_A <= 'd0;
ri_type_B <= 'd0;
ri_len_B <= 'd0;
ri_data_B <= 'd0;
ri_last_B <= 'd0;
ri_valid_B <= 'd0;
ri_valid_A_1d <= 'd0;
ri_valid_B_1d <= 'd0;
end else begin
ri_type_A <= i_type_A ;
ri_len_A <= i_len_A ;
ri_data_A <= i_data_A ;
ri_last_A <= i_last_A ;
ri_valid_A <= i_valid_A ;
ri_type_B <= i_type_B ;
ri_len_B <= i_len_B ;
ri_data_B <= i_data_B ;
ri_last_B <= i_last_B ;
ri_valid_B <= i_valid_B ;
ri_valid_A_1d <= ri_valid_A;
ri_valid_B_1d <= ri_valid_B;
end
end
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst) begin
r_fifo_A_rden_1d <= 'd0 ;
r_fifo_B_rden_1d <= 'd0 ;
end else begin
r_fifo_A_rden_1d <= r_fifo_A_rden;
r_fifo_B_rden_1d <= r_fifo_B_rden;
end
end
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst)
r_cnt <= 'd0;
else if(r_arbiter)
r_cnt <= 'd0;
else if(r_cnt == 8)
r_cnt <= r_cnt;
else if(r_arbiter == 0)
r_cnt <= r_cnt + 1;
else
r_cnt <= 'd0;
end
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst)
r_arbiter <= 'd0;
else if(ro_last)
r_arbiter <= 'd0;
else if(!w_fifo_A_empty && r_arbiter == 0 && r_cnt == 8)
r_arbiter <= 'd1;
else if(!w_fifo_B_empty && r_arbiter == 0 && r_cnt == 8)
r_arbiter <= 'd2;
else
r_arbiter <= r_arbiter;
end
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst)
ro_data <= 'd0;
else if(r_arbiter == 1)
ro_data <= w_fifo_A_dout;
else if(r_arbiter == 2)
ro_data <= w_fifo_B_dout;
else
ro_data <= 'd0;
end
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst)
ro_valid <= 'd0;
else
ro_valid <= r_fifo_rd[0];
end
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst)
ro_last <= 'd0;
else if(!w_rd_en & r_rd_en)
ro_last <= 'd1;
else
ro_last <= 'd0;
end
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst)
r_fifo_A_rden <= 'd0;
else if(r_arbiter == 1 && r_rd_cnt == ri_len_A - 1)
r_fifo_A_rden <= 'd0;
else if(r_arbiter == 1 && !w_fifo_A_empty && !ro_valid)
r_fifo_A_rden <= 'd1;
else
r_fifo_A_rden <= r_fifo_A_rden;
end
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst)
r_fifo_B_rden <= 'd0;
else if(r_arbiter == 2 && r_rd_cnt == ri_len_B - 1)
r_fifo_B_rden <= 'd0;
else if(r_arbiter == 2 && !w_fifo_B_empty && !ro_valid)
r_fifo_B_rden <= 'd1;
else
r_fifo_B_rden <= r_fifo_B_rden;
end
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst)
r_rd_cnt <= 'd0;
else if(r_arbiter == 1 && r_rd_cnt == ri_len_A - 1)
r_rd_cnt <= 'd0;
else if(r_arbiter == 2 && r_rd_cnt == ri_len_B - 1)
r_rd_cnt <= 'd0;
else if(r_fifo_A_rden | r_fifo_B_rden)
r_rd_cnt <= r_rd_cnt + 1;
else
r_rd_cnt <= r_rd_cnt;
end
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst)
r_fifo_rd <= 'd0;
else
r_fifo_rd <= {r_fifo_rd[0],(r_fifo_A_rden | r_fifo_B_rden)};
end
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst)
r_rd_en <= 'd0;
else
r_rd_en <= w_rd_en;
end
//流控的过程
//1. A的数据来了,但是B还有帧还没发完,先输出stop信号。
//2. stop时,会A先发打断,完成然后把B的帧发了。
//3. A是空的,B也是空的,并且还在stop状态,此时拉低stop信号,正常输出
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst)
ro_next_frame_stop <= 'd0;
else if(ro_next_frame_stop && r_arbiter == 2 && w_fifo_B_empty)
ro_next_frame_stop <= 'd0;
else if(r_arbiter == 1 && !w_fifo_B_empty)
ro_next_frame_stop <= 'd1;
else
ro_next_frame_stop <= ro_next_frame_stop;
end
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst) begin
r_rden_A_pos <= 'd0;
r_rden_B_pos <= 'd0;
end else begin
r_rden_A_pos <= w_rden_A_pos ;
r_rden_B_pos <= w_rden_B_pos ;
end
end
always@(posedge i_clk,posedge i_rst)
begin
if(i_rst) begin
ro_type <= 'd0;
ro_len <= 'd0;
end else if(r_arbiter == 1 && r_rden_A_pos) begin
ro_type <= w_A_type_len[31:16];
ro_len <= w_A_type_len[15:0];
end else if(r_arbiter == 2 && r_rden_B_pos) begin
ro_type <= w_B_type_len[31:16];
ro_len <= w_B_type_len[15:0];
end else begin
ro_type <= ro_type;
ro_len <= ro_len ;
end
end
endmodule
模块收发组合
1 MAC层收发
c
module Ethernet_MAC#(
parameter P_TARTGET_MAC = {8'h00,8'h00,8'h00,8'h00,8'h00,8'h00},
P_SOURCE_MAC = {8'h00,8'h00,8'h00,8'h00,8'h00,8'h00},
P_CRC_CHECK = 1
)(
input i_clk ,
input i_rst ,
/*--------info port--------*/
input [47:0] i_target_mac ,
input i_target_mac_valid ,
input [47:0] i_source_mac ,
input i_source_mac_valid ,
/*--------data port--------*/
input i_udp_valid ,
output o_udp_ready ,
input [15:0] i_send_type ,
input [15:0] i_send_len ,
input [7 :0] i_send_data ,
input i_send_last ,
input i_send_valid ,
output [7 :0] o_ip_data ,
output o_ip_last ,
output o_ip_valid ,
output [7 :0] o_arp_data ,
output o_arp_last ,
output o_arp_valid ,
output [47:0] o_rec_src_mac ,
output o_rec_src_valid ,
output o_crc_error ,
output o_crc_valid ,
/*--------GMII port--------*/
output [7 :0] o_GMII_data ,
output o_GMII_valid ,
input [7 :0] i_GMII_data ,
input i_GMII_valid
);
(* mark_debug = "true" *)wire [15:0] w_post_type ;
(* mark_debug = "true" *)wire [7 :0] w_post_data ;
(* mark_debug = "true" *)wire w_post_last ;
(* mark_debug = "true" *)wire w_post_valid ;
(* mark_debug = "true" *)wire [15:0] w_crc_post_type ;
(* mark_debug = "true" *)wire [7 :0] w_crc_post_data ;
(* mark_debug = "true" *)wire w_crc_post_last ;
(* mark_debug = "true" *)wire w_crc_post_valid ;
(* mark_debug = "true" *)wire w_crc_error ;
(* mark_debug = "true" *)wire w_crc_valid ;
assign o_crc_error = w_crc_error ;
assign o_crc_valid = w_crc_valid ;
MAC_tx#(
.P_TARTGET_MAC (P_TARTGET_MAC),
.P_SOURCE_MAC (P_SOURCE_MAC ),
.P_CRC_CHECK (P_CRC_CHECK )
)
MAC_tx_u0
(
.i_clk (i_clk ),
.i_rst (i_rst ),
.i_target_mac (i_target_mac ),
.i_target_mac_valid (i_target_mac_valid),
.i_source_mac (i_source_mac ),
.i_source_mac_valid (i_source_mac_valid),
.i_udp_valid (i_udp_valid ),
.o_udp_ready (o_udp_ready ),
.i_send_type (i_send_type ),
.i_send_len (i_send_len ),
.i_send_data (i_send_data ),
.i_send_last (i_send_last ),
.i_send_valid (i_send_valid ),
.o_GMII_data (o_GMII_data ),
.o_GMII_valid (o_GMII_valid )
);
mac_arp_ip_mux mac_arp_ip_mux_u0(
.i_clk (i_clk ),
.i_rst (i_rst ),
.i_type (w_crc_post_type ),
.i_data (w_crc_post_data ),
.i_last (w_crc_post_last ),
.i_valid (w_crc_post_valid ),
.o_ip_data (o_ip_data ),
.o_ip_last (o_ip_last ),
.o_ip_valid (o_ip_valid ),
.o_arp_data (o_arp_data ),
.o_arp_last (o_arp_last ),
.o_arp_valid (o_arp_valid )
);
CRC_Data_Pro CRC_Data_Pro_u0(
.i_clk (i_clk ),
.i_rst (i_rst ),
.i_per_type (w_post_type ),
.i_per_data (w_post_data ),
.i_per_last (w_post_last ),
.i_per_valid (w_post_valid ),
.i_per_crc_error (w_crc_error ),
.i_per_crc_valid (w_crc_valid ),
.o_post_type (w_crc_post_type ),
.o_post_data (w_crc_post_data ),
.o_post_last (w_crc_post_last ),
.o_post_valid (w_crc_post_valid )
);
MAC_rx#(
.P_TARTGET_MAC (P_TARTGET_MAC ),
.P_SOURCE_MAC (P_SOURCE_MAC ),
.P_CRC_CHECK (P_CRC_CHECK )
)
MAC_rx_u0
(
.i_clk (i_clk ),
.i_rst (i_rst ),
.i_target_mac (i_target_mac ),
.i_target_mac_valid (i_target_mac_valid),
.i_source_mac (i_source_mac ),
.i_source_mac_valid (i_source_mac_valid),
.o_post_type (w_post_type ),
.o_post_data (w_post_data ),
.o_post_last (w_post_last ),
.o_post_valid (w_post_valid ),
.o_rec_src_mac (o_rec_src_mac ),
.o_rec_src_valid (o_rec_src_valid ),
.o_crc_error (w_crc_error ),
.o_crc_valid (w_crc_valid ),
.i_GMII_data (i_GMII_data ),
.i_GMII_valid (i_GMII_valid )
);
endmodule
2 ARP层收发
c
module Ethernet_ARP#(
parameter P_TARGET_IP = {8'd192,8'd168,8'd1,8'd1},
parameter P_SOURCE_MAC = {8'h00,8'h00,8'h00,8'h00,8'h00,8'h00},
parameter P_SOURCE_IP = {8'd192,8'd168,8'd1,8'd2}
)(
input i_clk ,
input i_rst ,
input [31:0] i_source_ip ,
input i_s_ip_valid ,
input [47:0] i_source_mac ,
input i_s_mac_valid ,
input [31:0] i_target_ip ,
input i_target_valid ,
input [31:0] i_seek_ip ,
input i_seek_valid ,
output [47:0] o_rec_target_mac ,
output o_rec_target_valid ,
output [7 :0] o_mac_data ,
output o_mac_last ,
output o_mac_valid ,
input [7 :0] i_mac_data ,
input i_mac_last ,
input i_mac_valid
);
wire w_trig_reply ;
wire [47:0] w_rec_target_mac ;
wire [31:0] w_target_ip ;
wire w_rec_target_valid ;
wire [31:0] w_arp_seek_ip ;
wire w_arp_seek_valid ;
ARP_tx#(
.P_TARGET_IP (P_TARGET_IP ),
.P_SOURCE_MAC (P_SOURCE_MAC ),
.P_SOURCE_IP (P_SOURCE_IP )
)
ARP_tx_u0
(
.i_clk (i_clk ),
.i_rst (i_rst ),
.i_target_ip (i_target_ip ),
.i_target_valid (i_target_valid ),
.i_source_mac (i_source_mac ),
.i_s_mac_valid (i_s_mac_valid ),
.i_source_ip (i_source_ip ),
.i_s_ip_valid (i_s_ip_valid ),
.i_reply_mac (w_rec_target_mac ),
.i_trig_reply (w_trig_reply ),
.i_active_send (0),
.o_seek_ip (w_arp_seek_ip ),
.o_seek_valid (w_arp_seek_valid),
.o_mac_data (o_mac_data ),
.o_mac_last (o_mac_last ),
.o_mac_valid (o_mac_valid )
);
ARP_Table ARP_Table_u0(
.i_clk (i_clk ),
.i_rst (i_rst ),
.i_seek_ip (i_seek_ip ),
.i_seek_valid (i_seek_valid ),
.i_updata_ip (w_target_ip ),
.i_updata_mac (w_rec_target_mac ),
.i_updata_valid (w_rec_target_valid ),
.o_active_mac (o_rec_target_mac ),
.o_active_valid (o_rec_target_valid )
);
ARP_rx#(
.P_TARGET_IP (P_TARGET_IP ),
.P_SOURCE_MAC (P_SOURCE_MAC ),
.P_SOURCE_IP (P_SOURCE_IP )
)
ARP_rx_U0
(
.i_clk (i_clk ),
.i_rst (i_rst ),
.i_source_ip (i_source_ip ),
.i_s_ip_valid (i_s_ip_valid ),
.o_target_mac (w_rec_target_mac ),
.o_target_ip (w_target_ip ),
.o_target_valid (w_rec_target_valid ),
.o_tirg_reply (w_trig_reply ),
.i_mac_data (i_mac_data ),
.i_mac_last (i_mac_last ),
.i_mac_valid (i_mac_valid )
);
endmodule
2 IP层收发
c
module Ethernet_IP#(
parameter P_ST_TARGET_IP = {8'd192,8'd168,8'd1,8'd0},
parameter P_ST_SOURCE_IP = {8'd192,8'd168,8'd1,8'd1}
)(
input i_clk ,
input i_rst ,
/*--------info port --------*/
input [31:0] i_target_ip ,
input i_target_valid ,
input [31:0] i_source_ip ,
input i_source_valid ,
/*--------data port--------*/
input [7 :0] i_send_type ,
input [15:0] i_send_len ,
input [7 :0] i_send_data ,
input i_send_last ,
input i_send_valid ,
output [15:0] o_udp_len ,
output [7 :0] o_udp_data ,
output o_udp_last ,
output o_udp_valid ,
output [15:0] o_icmp_len ,
output [7 :0] o_icmp_data ,
output o_icmp_last ,
output o_icmp_valid ,
output [31:0] o_source_ip ,
output o_source_ip_valid ,
/*--------arp port--------*/
output [31:0] o_arp_seek_ip ,
output o_arp_seek_valid ,
/*--------mac port--------*/
output [15:0] o_mac_type ,
output [15:0] o_mac_len ,
output [7 :0] o_mac_data ,
output o_mac_last ,
output o_mac_valid ,
input [7 :0] i_mac_data ,
input i_mac_last ,
input i_mac_valid
);
IP_tx#(
.P_ST_TARGET_IP (P_ST_TARGET_IP ),
.P_ST_SOURCE_IP (P_ST_SOURCE_IP )
)
IP_tx_u0
(
.i_clk (i_clk ),
.i_rst (i_rst ),
.i_target_ip (i_target_ip ),
.i_target_valid (i_target_valid ),
.i_source_ip (i_source_ip ),
.i_source_valid (i_source_valid ),
.i_send_type (i_send_type ),
.i_send_len (i_send_len ),
.i_send_data (i_send_data ),
.i_send_last (i_send_last ),
.i_send_valid (i_send_valid ),
.o_arp_seek_ip (o_arp_seek_ip ),
.o_arp_seek_valid (o_arp_seek_valid ),
.o_mac_type (o_mac_type ),
.o_mac_len (o_mac_len ),
.o_mac_data (o_mac_data ),
.o_mac_last (o_mac_last ),
.o_mac_valid (o_mac_valid )
);
IP_rx#(
.P_ST_TARGET_IP (P_ST_TARGET_IP ),
.P_ST_SOURCE_IP (P_ST_SOURCE_IP )
)
IP_rx_u0
(
.i_clk (i_clk ),
.i_rst (i_rst ),
.i_target_ip (i_target_ip ),
.i_target_valid (i_target_valid ),
.i_source_ip (i_source_ip ),
.i_source_valid (i_source_valid ),
.o_udp_len (o_udp_len ),
.o_udp_data (o_udp_data ),
.o_udp_last (o_udp_last ),
.o_udp_valid (o_udp_valid ),
.o_icmp_len (o_icmp_len ),
.o_icmp_data (o_icmp_data ),
.o_icmp_last (o_icmp_last ),
.o_icmp_valid (o_icmp_valid ),
.o_source_ip (o_source_ip ),
.o_source_ip_valid (o_source_ip_valid ),
.i_mac_data (i_mac_data ),
.i_mac_last (i_mac_last ),
.i_mac_valid (i_mac_valid )
);
endmodule
3 ICMP层收发
c
module Ethernet_ICMP(
input i_clk ,
input i_rst ,
input [15:0] i_icmp_len ,
input [7 :0] i_icmp_data ,
input i_icmp_last ,
input i_icmp_valid ,
output [15:0] o_icmp_len ,
output [7 :0] o_icmp_data ,
output o_icmp_last ,
output o_icmp_valid
);
wire w_trig_reply ;
wire [31:0] w_trig_seq ;
ICMP_tx ICMP_tx_u0(
.i_clk (i_clk ),
.i_rst (i_rst ),
.i_trig_reply (w_trig_reply ),
.i_trig_seq (w_trig_seq ),
.o_icmp_len (o_icmp_len ),
.o_icmp_data (o_icmp_data ),
.o_icmp_last (o_icmp_last ),
.o_icmp_valid (o_icmp_valid )
);
ICMP_rx ICMP_rx_u0(
.i_clk (i_clk ),
.i_rst (i_rst ),
.i_icmp_len (i_icmp_len ),
.i_icmp_data (i_icmp_data ),
.i_icmp_last (i_icmp_last ),
.i_icmp_valid (i_icmp_valid ),
.o_trig_reply (w_trig_reply ),
.o_trig_seq (w_trig_seq )
);
endmodule
3 UDP层收发
c
module Ethernet_UDP#(
parameter P_TARGET_PORT = 16'h8080 ,
P_SOURCE_PORT = 16'h8080
)(
input i_clk ,
input i_rst ,
/*--------info port-------*/
input [15:0] i_target_port ,
input i_target_valid ,
input [15:0] i_source_port ,
input i_source_valid ,
/*--------data port--------*/
input [15:0] i_send_len ,
input [7 :0] i_send_data ,
input i_send_last ,
input i_send_valid ,
output [15:0] o_udp_len ,
output [7 :0] o_udp_data ,
output o_udp_last ,
output o_udp_valid ,
/*--------ip port--------*/
output [15:0] o_ip_len ,
output [7 :0] o_ip_data ,
output o_ip_last ,
output o_ip_valid ,
input [15:0] i_ip_len ,
input [7 :0] i_ip_data ,
input i_ip_last ,
input i_ip_valid
);
UDP_tx#(
.P_TARGET_PORT (P_TARGET_PORT),
.P_SOURCE_PORT (P_SOURCE_PORT)
)
UDP_tx_u0
(
.i_clk (i_clk ),
.i_rst (i_rst ),
.i_target_port (i_target_port ),
.i_target_valid (i_target_valid ),
.i_source_port (i_source_port ),
.i_source_valid (i_source_valid ),
.i_send_len (i_send_len ),
.i_send_data (i_send_data ),
.i_send_last (i_send_last ),
.i_send_valid (i_send_valid ),
.o_ip_len (o_ip_len ),
.o_ip_data (o_ip_data ),
.o_ip_last (o_ip_last ),
.o_ip_valid (o_ip_valid )
);
UDP_rx#(
.P_TARGET_PORT (P_TARGET_PORT),
.P_SOURCE_PORT (P_SOURCE_PORT)
)
UDP_rx_u0
(
.i_clk (i_clk ),
.i_rst (i_rst ),
.i_target_port (i_target_port ),
.i_target_valid (i_target_valid ),
.i_source_port (i_source_port ),
.i_source_valid (i_source_valid ),
.o_udp_len (o_udp_len ),
.o_udp_data (o_udp_data ),
.o_udp_last (o_udp_last ),
.o_udp_valid (o_udp_valid ),
.i_ip_len (i_ip_len ),
.i_ip_data (i_ip_data ),
.i_ip_last (i_ip_last ),
.i_ip_valid (i_ip_valid )
);
endmodule
UDP协议栈
c
module UDP_Stack_Module#(
parameter P_TARGET_PORT = 16'h8080 ,
P_SOURCE_PORT = 16'h8080 ,
P_TARGET_IP = {8'd192,8'd168,8'd1,8'd0} ,
P_SOURCE_IP = {8'd192,8'd168,8'd1,8'd1} ,
P_TARTGET_MAC = {8'h00,8'h00,8'h00,8'h00,8'h00,8'h00} ,
P_SOURCE_MAC = {8'h00,8'h00,8'h00,8'h00,8'h00,8'h00} ,
P_CRC_CHEKC = 1
)(
input i_clk ,
input i_rst ,
/*--------info port-------*/
input [15:0] i_target_port ,
input i_target_port_valid ,
input [15:0] i_source_port ,
input i_source_port_valid ,
input [31:0] i_target_ip ,
input i_target_ip_valid ,
input [31:0] i_source_ip ,
input i_source_ip_valid ,
input [47:0] i_target_mac ,
input i_target_mac_valid ,
input [47:0] i_source_mac ,
input i_source_mac_valid ,
/*--------data port--------*/
input [15:0] i_send_len ,
input [7 :0] i_send_data ,
input i_send_last ,
input i_send_valid ,
output o_send_ready ,
output [15:0] o_rec_len ,
output [7 :0] o_rec_data ,
output o_rec_last ,
output o_rec_valid ,
output [31:0] o_source_ip ,
output o_source_ip_valid ,
output [47:0] o_rec_src_mac ,
output o_rec_src_valid ,
output o_crc_error ,
output o_crc_valid ,
/*--------GMII port--------*/
output [7 :0] o_GMII_data ,
output o_GMII_valid ,
input [7 :0] i_GMII_data ,
input i_GMII_valid
);
wire w_udp_ready ;
wire w_ip_next_frame_stop ;
wire w_udp_next_frame_stop ;
wire [15:0] w_udp2ip_len ;
wire [7 :0] w_udp2ip_data ;
wire w_udp2ip_last ;
wire w_udp2ip_valid ;
(* mark_debug = "true" *)wire [15:0] w_ip2udp_len ;
(* mark_debug = "true" *)wire [7 :0] w_ip2udp_data ;
(* mark_debug = "true" *)wire w_ip2udp_last ;
(* mark_debug = "true" *)wire w_ip2udp_valid ;
wire [15:0] w_icmp_rec_len ;
wire [7 :0] w_icmp_rec_data ;
wire w_icmp_rec_last ;
wire w_icmp_rec_valid ;
wire [15:0] w_icmp_send_len ;
wire [7 :0] w_icmp_send_data ;
wire w_icmp_send_last ;
wire w_icmp_send_valid ;
wire [15:0] w_icmp_udp_type ;
wire [15:0] w_icmp_udp_len ;
wire [7 :0] w_icmp_udp_data ;
wire w_icmp_udp_last ;
wire w_icmp_udp_valid ;
wire [47:0] w_arp_rec_target_mac ;
wire w_arp_rec_target_valid ;
wire [7 :0] w_arp2mac_data ;
wire w_arp2mac_last ;
wire w_arp2mac_valid ;
wire [7 :0] w_mac2arp_data ;
wire w_mac2arp_last ;
wire w_mac2arp_valid ;
wire [15:0] w_ip2mac_type ;
wire [15:0] w_ip2mac_len ;
wire [7 :0] w_ip2mac_data ;
wire w_ip2mac_last ;
wire w_ip2mac_valid ;
(* mark_debug = "true" *)wire [7 :0] w_mac2ip_data ;
(* mark_debug = "true" *)wire w_mac2ip_last ;
(* mark_debug = "true" *)wire w_mac2ip_valid ;
wire [15:0] w_ip_icmp_2_mac_type ;
wire [15:0] w_ip_icmp_2_mac_len ;
wire [7 :0] w_ip_icmp_2_mac_data ;
wire w_ip_icmp_2_mac_last ;
wire w_ip_icmp_2_mac_valid ;
wire [31:0] w_arp_seek_ip ;
wire w_arp_seek_valid ;
wire w_send_ready ;
reg ro_send_ready ;
reg [7 :0] r_ready_cnt ;
reg ri_send_valid ;
assign o_send_ready = w_send_ready;
assign w_send_ready = ~w_ip_next_frame_stop & ~w_udp_next_frame_stop & w_udp_ready;
Ethernet_UDP#(
.P_TARGET_PORT (P_TARGET_PORT ),
.P_SOURCE_PORT (P_SOURCE_PORT )
)
Ethernet_UDP_u0
(
.i_clk (i_clk ),
.i_rst (i_rst ),
.i_target_port (i_target_port ),
.i_target_valid (i_target_port_valid),
.i_source_port (i_source_port ),
.i_source_valid (i_source_port_valid),
.i_send_len (i_send_len ),
.i_send_data (i_send_data ),
.i_send_last (i_send_last ),
.i_send_valid (i_send_valid ),
.o_udp_len (o_rec_len ),
.o_udp_data (o_rec_data ),
.o_udp_last (o_rec_last ),
.o_udp_valid (o_rec_valid ),
.o_ip_len (w_udp2ip_len ),
.o_ip_data (w_udp2ip_data ),
.o_ip_last (w_udp2ip_last ),
.o_ip_valid (w_udp2ip_valid ),
.i_ip_len (w_ip2udp_len ),
.i_ip_data (w_ip2udp_data ),
.i_ip_last (w_ip2udp_last ),
.i_ip_valid (w_ip2udp_valid )
);
Ethernet_ICMP Ethernet_ICMP_u0(
.i_clk (i_clk ),
.i_rst (i_rst ),
.i_icmp_len (w_icmp_rec_len ),
.i_icmp_data (w_icmp_rec_data ),
.i_icmp_last (w_icmp_rec_last ),
.i_icmp_valid (w_icmp_rec_valid ),
.o_icmp_len (w_icmp_send_len ),
.o_icmp_data (w_icmp_send_data ),
.o_icmp_last (w_icmp_send_last ),
.o_icmp_valid (w_icmp_send_valid )
);
Data_2to1 Data_2to1_ICMP_UDP(
.i_clk (i_clk ),
.i_rst (i_rst ),
.i_type_A (17 ),
.i_len_A (w_udp2ip_len ),
.i_data_A (w_udp2ip_data ),
.i_last_A (w_udp2ip_last ),
.i_valid_A (w_udp2ip_valid ),
.o_next_frame_stop (w_udp_next_frame_stop),
.i_type_B (1 ),
.i_len_B (w_icmp_send_len ),
.i_data_B (w_icmp_send_data ),
.i_last_B (w_icmp_send_last ),
.i_valid_B (w_icmp_send_valid ),
.o_type (w_icmp_udp_type ),
.o_len (w_icmp_udp_len ),
.o_data (w_icmp_udp_data ),
.o_last (w_icmp_udp_last ),
.o_valid (w_icmp_udp_valid )
);
Ethernet_ARP#(
.P_TARGET_IP (P_TARGET_IP ),
.P_SOURCE_MAC (P_SOURCE_MAC ),
.P_SOURCE_IP (P_SOURCE_IP )
)
Ethernet_ARP_u0
(
.i_clk (i_clk ),
.i_rst (i_rst ),
.i_source_ip (i_source_ip ),
.i_s_ip_valid (i_source_ip_valid ),
.i_source_mac (i_source_mac ),
.i_s_mac_valid (i_source_mac_valid ),
.i_target_ip (i_target_ip ),
.i_target_valid (i_target_ip_valid ),
.i_seek_ip (w_arp_seek_ip ),
.i_seek_valid (w_arp_seek_valid ),
.o_rec_target_mac (w_arp_rec_target_mac ),
.o_rec_target_valid (w_arp_rec_target_valid ),
.o_mac_data (w_arp2mac_data ),
.o_mac_last (w_arp2mac_last ),
.o_mac_valid (w_arp2mac_valid ),
.i_mac_data (w_mac2arp_data ),
.i_mac_last (w_mac2arp_last ),
.i_mac_valid (w_mac2arp_valid )
);
Ethernet_IP#(
.P_ST_TARGET_IP (P_TARGET_IP ),
.P_ST_SOURCE_IP (P_SOURCE_IP )
)
Ethernet_IP_u0
(
.i_clk (i_clk ),
.i_rst (i_rst ),
.i_target_ip (i_target_ip ),
.i_target_valid (i_target_ip_valid ),
.i_source_ip (i_source_ip ),
.i_source_valid (i_source_ip_valid ),
.i_send_type (w_icmp_udp_type[7 :0] ),
.i_send_len (w_icmp_udp_len ),
.i_send_data (w_icmp_udp_data ),
.i_send_last (w_icmp_udp_last ),
.i_send_valid (w_icmp_udp_valid ),
.o_udp_len (w_ip2udp_len ),
.o_udp_data (w_ip2udp_data ),
.o_udp_last (w_ip2udp_last ),
.o_udp_valid (w_ip2udp_valid ),
.o_icmp_len (w_icmp_rec_len ),
.o_icmp_data (w_icmp_rec_data ),
.o_icmp_last (w_icmp_rec_last ),
.o_icmp_valid (w_icmp_rec_valid ),
.o_source_ip (o_source_ip ),
.o_source_ip_valid (o_source_ip_valid ),
.o_arp_seek_ip (w_arp_seek_ip ),
.o_arp_seek_valid (w_arp_seek_valid ),
.o_mac_type (w_ip2mac_type ),
.o_mac_len (w_ip2mac_len ),
.o_mac_data (w_ip2mac_data ),
.o_mac_last (w_ip2mac_last ),
.o_mac_valid (w_ip2mac_valid ),
.i_mac_data (w_mac2ip_data ),
.i_mac_last (w_mac2ip_last ),
.i_mac_valid (w_mac2ip_valid )
);
Data_2to1 Data_2to1_ARP_IP(
.i_clk (i_clk ),
.i_rst (i_rst ),
.i_type_A (16'h0806 ),
.i_len_A (50 ),
.i_data_A (w_arp2mac_data ),
.i_last_A (w_arp2mac_last ),
.i_valid_A (w_arp2mac_valid ),
.o_next_frame_stop (w_ip_next_frame_stop),
.i_type_B (w_ip2mac_type ),
.i_len_B (w_ip2mac_len ),
.i_data_B (w_ip2mac_data ),
.i_last_B (w_ip2mac_last ),
.i_valid_B (w_ip2mac_valid ),
.o_type (w_ip_icmp_2_mac_type ),
.o_len (w_ip_icmp_2_mac_len ),
.o_data (w_ip_icmp_2_mac_data ),
.o_last (w_ip_icmp_2_mac_last ),
.o_valid (w_ip_icmp_2_mac_valid )
);
Ethernet_MAC#(
.P_TARTGET_MAC (P_TARTGET_MAC ),
.P_SOURCE_MAC (P_SOURCE_MAC ),
.P_CRC_CHECK (P_CRC_CHEKC )
)
Ethernet_MAC_u0
(
.i_clk (i_clk ),
.i_rst (i_rst ),
.i_target_mac (w_arp_rec_target_mac ),
.i_target_mac_valid (w_arp_rec_target_valid ),
.i_source_mac (i_source_mac ),
.i_source_mac_valid (i_source_mac_valid ),
.i_udp_valid (i_send_valid ),
.o_udp_ready (w_udp_ready ),
.i_send_type (w_ip_icmp_2_mac_type ),
.i_send_len (w_ip_icmp_2_mac_len ),
.i_send_data (w_ip_icmp_2_mac_data ),
.i_send_last (w_ip_icmp_2_mac_last ),
.i_send_valid (w_ip_icmp_2_mac_valid ),
.o_ip_data (w_mac2ip_data ),
.o_ip_last (w_mac2ip_last ),
.o_ip_valid (w_mac2ip_valid ),
.o_arp_data (w_mac2arp_data ),
.o_arp_last (w_mac2arp_last ),
.o_arp_valid (w_mac2arp_valid ),
.o_rec_src_mac (o_rec_src_mac ),
.o_rec_src_valid (o_rec_src_valid ),
.o_crc_error (o_crc_error ),
.o_crc_valid (o_crc_valid ),
.o_GMII_data (o_GMII_data ),
.o_GMII_valid (o_GMII_valid ),
.i_GMII_data (i_GMII_data ),
.i_GMII_valid (i_GMII_valid )
);
endmodule
有问题可以加企鹅群 658476482 交流