【IP层的校验和与UDP的校验和】+【FPGA实现】
MAC层的校验是CRC,而IP层也有其校验机制。
CRC保证数据包的传输正确;
IP头校验和
FPGA实现:
module checksum_ip_buffer #( parameter UDP_CODE = 8'h11 , parameter TX_TARGET_PORT = 16'd808 , parameter TX_SOURCE_PORT = 16'd8080 , parameter RX_Sync_Frame = 32'hF05AA50F , parameter TX_SOURCE_Addr = {8'd192,8'd168,8'd0,8'd1} , parameter TX_TARGET_Addr = {8'hFF,8'hFF,8'hFF,8'hFF} , //Length parameter TX_PREAMBLE = {8'h55,8'h55,8'h55,8'h55,8'h55,8'h55,8'h55,8'hD5}, parameter TX_TARGET_MAC = {8'hFF,8'hFF,8'hFF,8'hFF,8'hFF,8'hFF} ,// broadcast packet parameter TX_SOURECE_MAC = {8'hA8,8'hB2,8'h3C,8'h7D,8'h97,8'hD7} , parameter Length_HeartBeat = 16'd92 , parameter Length_UDP = 16'd72 , parameter Length_HeartBeat_all = 8'd114 , parameter Length_EnCODE_Packet = 8'd114 )( input wire sys_clk , input wire sys_rst_n , input wire i_vaild , input wire [7:0] i_data , output wire o_vaild , output wire [7:0] o_data ); reg [15:0] i_vaild_cnt ; reg [15:0] r_i_vaild ; reg [07:0] r1_i_data ; wire [15:0] concat_data ; //IP check sum reg [01:0] ip_concat_cnt ; reg [01:0] udp_concat_cnt ; reg [31:0] r1_IPsum ; wire [31:0] r1_IPchecksum_value ; reg [15:0] r2_IPchecksum_value ; //UDP check sum reg udp_reg ; reg [31:0] r1_UDPsum ; wire [31:0] r1_UDPchecksum_value ; wire [15:0] r2_UDPchecksum_value ; reg [15:0] r3_UDPchecksum_value ; //rd reg rd_cycle ; reg [15:0] rd_cnt ; reg [15:0] r_rd_cnt ; reg r1_o_vaild ; reg r2_o_vaild ; reg [07:0] r1_o_data ; wire [07:0] rd_data ; wire [31:00] Faker_header ; wire [15:00] length_check ; wire length_check_flag ; assign Faker_header = TX_SOURCE_Addr[31:16] + TX_SOURCE_Addr[15:00] + TX_TARGET_Addr[31:16] + TX_TARGET_Addr[15:00] + {8'h00,UDP_CODE} + Length_UDP; assign length_check = Length_UDP - 'd8; assign length_check_flag = (length_check[0] == 0)?(1'b0):(1'b1); always @(posedge sys_clk) begin r_i_vaild <= {r_i_vaild[14:0],i_vaild}; r1_o_vaild <= rd_cycle; r2_o_vaild <= r1_o_vaild; r1_i_data <= i_data; r_rd_cnt <= rd_cnt; end always @(posedge sys_clk) begin if(sys_rst_n == 1'b0) begin i_vaild_cnt <= 8'h0; end else if(i_vaild == 1'b1) begin if(i_vaild_cnt == Length_EnCODE_Packet - 1'b1) begin i_vaild_cnt <= 8'h0; end else begin i_vaild_cnt <= i_vaild_cnt + 1'b1; end end end assign concat_data = {r1_i_data,i_data}; always @(posedge sys_clk) begin if(sys_rst_n == 1'b0) begin ip_concat_cnt <= 2'd0; end else if(i_vaild == 1'b0 && r_i_vaild[0] == 1'b1) begin ip_concat_cnt <= 2'd0; end else if(i_vaild == 1'b1 && i_vaild_cnt >= 'd22 && i_vaild_cnt <= 41) begin if(ip_concat_cnt == 1'b1) begin ip_concat_cnt <= 2'd0; end else begin ip_concat_cnt <= ip_concat_cnt + 1'b1; end end else begin ip_concat_cnt <= ip_concat_cnt; end end always @(posedge sys_clk) begin if(sys_rst_n == 1'b0) begin r1_IPsum <= 32'd0; end else if(i_vaild == 1'b0 && r_i_vaild[0] == 1'b1) begin r1_IPsum <= 32'd0; end else if(i_vaild == 1'b1 && i_vaild_cnt >= 'd22 && i_vaild_cnt <= 'd41 && ip_concat_cnt == 1'b1) begin r1_IPsum <= r1_IPsum + concat_data; end else begin r1_IPsum <= r1_IPsum; end end assign r1_IPchecksum_value = r1_IPsum[15:0] + r1_IPsum[31:16]; always @(posedge sys_clk) begin if(sys_rst_n == 1'b0) begin r2_IPchecksum_value <= 'd0; end else if(rd_cycle == 1'b1 && rd_cnt == Length_EnCODE_Packet - 1'b1) begin r2_IPchecksum_value <= 'd0; end else if(i_vaild == 1'b1 && i_vaild_cnt == 'd42) begin r2_IPchecksum_value <= ~(r1_IPchecksum_value[15:0]); end end // UDP always @(posedge sys_clk) begin if(sys_rst_n == 1'b0) begin udp_concat_cnt <= 2'd0; end else if(i_vaild == 1'b0 && r_i_vaild[0] == 1'b1) begin udp_concat_cnt <= 2'd0; end else if(i_vaild == 1'b1 && ((i_vaild_cnt >= 42 && i_vaild_cnt <= 49) || (i_vaild_cnt >= 'd50 && i_vaild_cnt <= Length_EnCODE_Packet - 1'b1))) begin if(udp_concat_cnt == 1'b1) begin udp_concat_cnt <= 2'd0; end else begin udp_concat_cnt <= udp_concat_cnt + 1'b1; end end else begin udp_concat_cnt <= udp_concat_cnt; end end always @(posedge sys_clk) begin if(sys_rst_n == 1'b0) begin udp_reg <= 1'b0; end else if(i_vaild == 1'b1 && i_vaild_cnt == Length_EnCODE_Packet - 1'b1) begin udp_reg <= 1'b1; end else begin udp_reg <= 1'b0; end end always @(posedge sys_clk) begin if(sys_rst_n == 1'b0) begin r1_UDPsum <= 'd0; end else if(rd_cycle == 1'b1 && rd_cnt == Length_EnCODE_Packet - 1'b1) begin r1_UDPsum <= 'd0; end else if(i_vaild == 1'b1 && r_i_vaild == 1'b0) begin r1_UDPsum <= Faker_header; end else if(i_vaild == 1'b1 && udp_concat_cnt == 1'b1 && ((i_vaild_cnt >= 'd42 && i_vaild_cnt <= 'd49) || (i_vaild_cnt >= 'd50 && i_vaild_cnt <= Length_EnCODE_Packet - 1'b1))) begin r1_UDPsum <= r1_UDPsum + concat_data; end else begin r1_UDPsum <= r1_UDPsum; end end assign r1_UDPchecksum_value = r1_UDPsum[15:0] + r1_UDPsum[31:16]; assign r2_UDPchecksum_value = ~(r1_UDPchecksum_value[15:0]); always @(posedge sys_clk) begin if(sys_rst_n == 1'b0) begin r3_UDPchecksum_value <= 'd0; end else if(rd_cycle == 1'b1 && rd_cnt == Length_EnCODE_Packet - 1'b1) begin r3_UDPchecksum_value <= 'd0; end else if(udp_reg == 1'b1) begin r3_UDPchecksum_value <= r2_UDPchecksum_value; end end always @(posedge sys_clk) begin if(sys_rst_n == 1'b0) begin rd_cycle <= 1'b0; end else if(rd_cycle == 1'b1 && rd_cnt == Length_EnCODE_Packet - 1'b1) begin rd_cycle <= 1'b0; end else if(rd_cycle == 1'b0 && i_vaild == 1'b1 && i_vaild_cnt == Length_EnCODE_Packet - 1'b1) begin rd_cycle <= 1'b1; end end always @(posedge sys_clk) begin if(sys_rst_n == 1'b0) begin rd_cnt <= 8'h0; end else if(rd_cycle == 1'b1) begin if(rd_cnt == Length_EnCODE_Packet - 1'b1) begin rd_cnt <= 8'h0; end else begin rd_cnt <= rd_cnt + 1'b1; end end end always @(posedge sys_clk) begin if(sys_rst_n == 1'b0) begin r1_o_data <= 8'h0; end else if(r1_o_vaild == 1'b1 && r_rd_cnt == 'd32) begin r1_o_data <= r2_IPchecksum_value[15:08]; end else if(r1_o_vaild == 1'b1 && r_rd_cnt == 'd33) begin r1_o_data <= r2_IPchecksum_value[07:00]; end else if(r1_o_vaild == 1'b1 && r_rd_cnt == 'd48) begin r1_o_data <= r3_UDPchecksum_value[15:08]; end else if(r1_o_vaild == 1'b1 && r_rd_cnt == 'd49) begin r1_o_data <= r3_UDPchecksum_value[07:00]; end else if(r1_o_vaild == 1'b1) begin r1_o_data <= rd_data; end else begin r1_o_data <= 8'hff; end end assign o_vaild = r2_o_vaild; assign o_data = r1_o_data; buffer_encode buffer_encode_inst0 ( .clka ( sys_clk ), // input wire clka .wea ( i_vaild ), // input wire [0 : 0] wea .addra( i_vaild_cnt ), // input wire [6 : 0] addra .dina ( i_data ), // input wire [7 : 0] dina .clkb ( sys_clk ), // input wire clkb .addrb( rd_cnt ), // input wire [6 : 0] addrb .doutb( rd_data ) // output wire [7 : 0] doutb ); endmodule