一、模块功能
1、解析目的IP是否是本节点的源IP,如果是则进行如下的处理,如果不是则无需上上级传递
2、提取MAC层发送过来的IP报文,并提取其中的数据字段(上层协议字段),传递给上级
3、提取IP报文头中的关键字段,例如数据长度、标识、是否分片、分片偏移等,组合成user数据传递给上级
注:本模块暂时没有做头部校验
二、模块代码
`timescale 1ns / 1ps
//
// Company:
// Engineer:
//
// Create Date: 2024/05/14 10:11:58
// Design Name:
// Module Name: IP_RX
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//
module IP_RX#(
parameter P_SOURCE_IP = {8'd192,8'd168,8'd100,8'd100}
)(
input i_clk ,
input i_rst ,
input [31:0] i_set_source_ip ,
input i_set_source_valid ,
input [63:0] s_axis_mac_data ,
input [79:0] s_axis_mac_user ,//16'dlen,48'dsource_mac,16'dtype
input [7 :0] s_axis_mac_keep ,
input s_axis_mac_last ,
input s_axis_mac_valid ,
output [63:0] m_axis_out_data ,
output [54:0] m_axis_out_user ,//16'dlen,1'bsplit,8'dtype,13'doffset,16'dID
output [7 :0] m_axis_out_keep ,
output m_axis_out_last ,
output m_axis_out_valid
);
reg [63:0] rm_axis_out_data ;
reg [54:0] rm_axis_out_user ;
reg [7 :0] rm_axis_out_keep ;
reg rm_axis_out_last ;
reg rm_axis_out_valid ;
reg [63:0] rs_axis_mac_data ;
reg [79:0] rs_axis_mac_user ;
reg [7 :0] rs_axis_mac_keep ;
reg rs_axis_mac_last ;
reg rs_axis_mac_valid ;
reg [31:0] ri_set_source_ip ;
reg ri_set_source_valid ;
reg [15:0] r_len ;
reg [15:0] r_ID ;
reg r_slip ;
reg r_MF ;
reg [12:0] r_offset ;
reg [7 :0] r_type ;
reg [31:0] r_source_ip ;
reg [31:0] r_dest_ip ;
reg [15:0] r_cnt ;
reg r_ip_check ;
reg [7 :0] r_last_keep ;
assign m_axis_out_data = rm_axis_out_data ;
assign m_axis_out_user = rm_axis_out_user ;
assign m_axis_out_keep = rm_axis_out_keep ;
assign m_axis_out_last = rm_axis_out_last ;
assign m_axis_out_valid = rm_axis_out_valid ;
always@(posedge i_clk,posedge i_rst)begin
if(i_rst)begin
rs_axis_mac_data <= 'd0;
rs_axis_mac_user <= 'd0;
rs_axis_mac_keep <= 'd0;
rs_axis_mac_last <= 'd0;
rs_axis_mac_valid <= 'd0;
end
else begin
rs_axis_mac_data <= s_axis_mac_data ;
rs_axis_mac_user <= s_axis_mac_user ;
rs_axis_mac_keep <= s_axis_mac_keep ;
rs_axis_mac_last <= s_axis_mac_last ;
rs_axis_mac_valid <= s_axis_mac_valid ;
end
end
always@(posedge i_clk,posedge i_rst)begin
if(i_rst)
r_last_keep <= 'd0;
else
if(s_axis_mac_last)
r_last_keep <= s_axis_mac_keep;
else
r_last_keep <= r_last_keep;
end
always@(posedge i_clk,posedge i_rst)begin
if(i_rst)
r_cnt <= 'd0;
else
if(s_axis_mac_valid)
r_cnt <= r_cnt + 1;
else if(rm_axis_out_last)
r_cnt <= 'd0;
else
r_cnt <= r_cnt ;
end
always@(posedge i_clk,posedge i_rst)begin
if(i_rst)
r_len <= 'd0;
else
if(s_axis_mac_valid && r_cnt == 0)
r_len <= s_axis_mac_data[47:32] - 20;
else
r_len <= r_len;
end
always@(posedge i_clk,posedge i_rst)begin
if(i_rst)
r_ID <= 'd0;
else
if(s_axis_mac_valid && r_cnt == 0)
r_ID <= s_axis_mac_data[31:16];
else
r_ID <= r_ID;
end
always@(posedge i_clk,posedge i_rst)begin
if(i_rst)
r_slip <= 'd0;
else
if(s_axis_mac_valid && r_cnt == 0)
r_slip <= ~s_axis_mac_data[14];
else
r_slip <= r_slip;
end
always@(posedge i_clk,posedge i_rst)begin
if(i_rst)
r_MF <= 'd0;
else
if(s_axis_mac_valid && r_cnt == 0)
r_MF <= s_axis_mac_data[13];
else
r_MF <= r_MF;
end
always@(posedge i_clk,posedge i_rst)begin
if(i_rst)
r_offset <= 'd0;
else
if(s_axis_mac_valid && r_cnt == 0)
r_offset <= s_axis_mac_data[12:0];
else
r_offset <= r_offset;
end
always@(posedge i_clk,posedge i_rst)begin
if(i_rst)
r_type <= 'd0;
else
if(s_axis_mac_valid && r_cnt == 1)
r_type <= s_axis_mac_data[47:40];
else
r_type <= r_type;
end
always@(posedge i_clk,posedge i_rst)begin
if(i_rst)
r_source_ip <= 'd0;
else
if(s_axis_mac_valid && r_cnt == 1)
r_source_ip <= s_axis_mac_data[31:0];
else
r_source_ip <= r_source_ip;
end
always@(posedge i_clk,posedge i_rst)begin
if(i_rst)
r_dest_ip <= 'd0;
else
if(s_axis_mac_valid && r_cnt == 2)
r_dest_ip <= s_axis_mac_data[63:32];
else
r_dest_ip <= r_dest_ip;
end
always@(posedge i_clk,posedge i_rst)begin
if(i_rst)
ri_set_source_ip <= P_SOURCE_IP;
else
if(i_set_source_valid)
ri_set_source_ip <= i_set_source_ip;
else
ri_set_source_ip <= ri_set_source_ip;
end
always@(posedge i_clk,posedge i_rst)begin
if(i_rst)
r_ip_check <= 'd0;
else
if(s_axis_mac_valid && r_cnt == 2 && (s_axis_mac_data[63:32] == r_source_ip))
r_ip_check <= 1'b1;
else if(s_axis_mac_valid && r_cnt == 2 && (s_axis_mac_data[63:32] != r_source_ip))
r_ip_check <= 1'b0;
else
r_ip_check <= r_ip_check;
end
//解析数据
always@(posedge i_clk,posedge i_rst)begin
if(i_rst)
rm_axis_out_data <= 'd0;
else
rm_axis_out_data <= {rs_axis_mac_data[31:0],s_axis_mac_data[63:32]};
end
always@(posedge i_clk,posedge i_rst)begin
if(i_rst)
rm_axis_out_keep <= 'd0;
else
if(rs_axis_mac_last && r_last_keep >= 8'b1111_1000)
case(r_last_keep)
8'b1111_1111: rm_axis_out_keep <= 8'b1111_0000;
8'b1111_1110: rm_axis_out_keep <= 8'b1110_0000;
8'b1111_1100: rm_axis_out_keep <= 8'b1100_0000;
8'b1111_1000: rm_axis_out_keep <= 8'b1000_0000;
default : rm_axis_out_keep <= 8'b0000_0000;
endcase
else if(s_axis_mac_last && s_axis_mac_keep <= 8'b1111_0000)
case(s_axis_mac_keep)
8'b1111_0000: rm_axis_out_keep <= 8'b1111_1111;
8'b1110_0000: rm_axis_out_keep <= 8'b1111_1110;
8'b1100_0000: rm_axis_out_keep <= 8'b1111_1100;
8'b1000_0000: rm_axis_out_keep <= 8'b1111_1000;
default : rm_axis_out_keep <= 8'b1111_1111;
endcase
else
rm_axis_out_keep <= 8'b1111_1111;
end
always@(posedge i_clk,posedge i_rst)begin
if(i_rst)
rm_axis_out_valid <= 'd0;
else
if(r_cnt == 2)
rm_axis_out_valid <= 1'b1;
else if(rm_axis_out_last)
rm_axis_out_valid <= 1'b0;
else
rm_axis_out_valid <= rm_axis_out_valid;
end
always@(posedge i_clk,posedge i_rst)begin
if(i_rst)
rm_axis_out_last <= 'd0;
else
if((s_axis_mac_keep <= 8'b1111_0000) && s_axis_mac_last)
rm_axis_out_last <= 1'b1;
else if((r_last_keep > 8'b1111_0000) && rs_axis_mac_last)
rm_axis_out_last <= 1'b1;
else
rm_axis_out_last <= 1'b0;
end
always@(posedge i_clk,posedge i_rst)begin
if(i_rst)
rm_axis_out_user <= 'd0;
else
rm_axis_out_user <= {r_MF,r_len,r_slip,r_type,r_offset,r_ID};
end
endmodule
三、仿真图如下
数据包的目的IP地址要等与本节点的源IP地址,IP地址校验通过
解析IP报文头中的关键字段,并将IP报文中的数据解出