1. <ul id="0c1fb"></ul>

      <noscript id="0c1fb"><video id="0c1fb"></video></noscript>
      <noscript id="0c1fb"><listing id="0c1fb"><thead id="0c1fb"></thead></listing></noscript>

      99热在线精品一区二区三区_国产伦精品一区二区三区女破破_亚洲一区二区三区无码_精品国产欧美日韩另类一区

      RELATEED CONSULTING
      相關(guān)咨詢
      選擇下列產(chǎn)品馬上在線溝通
      服務(wù)時(shí)間:8:30-17:00
      你可能遇到了下面的問題
      關(guān)閉右側(cè)工具欄

      新聞中心

      這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷解決方案
      基于FPGA的UDP通信(五)-創(chuàng)新互聯(lián)

      站在用戶的角度思考問題,與客戶深入溝通,找到海原網(wǎng)站設(shè)計(jì)與海原網(wǎng)站推廣的解決方案,憑借多年的經(jīng)驗(yàn),讓設(shè)計(jì)與互聯(lián)網(wǎng)技術(shù)結(jié)合,創(chuàng)造個(gè)性化、用戶體驗(yàn)好的作品,建站類型包括:網(wǎng)站建設(shè)、成都網(wǎng)站建設(shè)、企業(yè)官網(wǎng)、英文網(wǎng)站、手機(jī)端網(wǎng)站、網(wǎng)站推廣、域名注冊(cè)雅安服務(wù)器托管、企業(yè)郵箱。業(yè)務(wù)覆蓋海原地區(qū)。

      引言

      前文鏈接:

      基于FPGA的UDP 通信(一)

      基于FPGA的UDP 通信(二)

      基于FPGA的UDP 通信(三)

      基于FPGA的UDP 通信(四)

      本文基于FPGA設(shè)計(jì)千兆以太網(wǎng)通信模塊UDP數(shù)據(jù)發(fā)送模塊(FPGA發(fā)送)

      設(shè)計(jì)條件

      FPGA芯片:xc7a35tfgg484-2

      網(wǎng)絡(luò)芯片(PHY):RTL8211(支持1000M/100M/10M)

      MAC與PHY接口:GMII

      接口類型:RJ-45

      Vivado版本:2018.3



      設(shè)計(jì)說明

      UDP數(shù)據(jù)發(fā)送模塊需要按照以太網(wǎng)的幀數(shù)據(jù)格式將數(shù)據(jù)發(fā)送,采用狀態(tài)機(jī)的方式實(shí)現(xiàn)。設(shè)計(jì)模塊主要包含如下幾部分:

      1、IP首部校驗(yàn)和計(jì)算模塊;

      2、FCS計(jì)算模塊(CRC32);

      3、UDP數(shù)據(jù)發(fā)送主模塊;

      FSC計(jì)算稍許復(fù)雜,此處給出時(shí)序圖(FCS發(fā)送部分時(shí)序):

      此處做簡(jiǎn)要說明:

      根據(jù)以太網(wǎng)數(shù)據(jù)協(xié)議,參與CRC32校驗(yàn)運(yùn)算的數(shù)據(jù)從 以太網(wǎng)數(shù)據(jù)頭到最后一個(gè)UDP數(shù)據(jù),最開始的FCS發(fā)送狀態(tài)發(fā)送的數(shù)據(jù)全為0,不參與CRC32校驗(yàn)計(jì)算,由于CRC校驗(yàn)計(jì)算延遲為 1個(gè)時(shí)鐘周期,所以需要對(duì)原狀態(tài)機(jī)的發(fā)送數(shù)據(jù)延遲一個(gè)時(shí)鐘周期后送入 GMII接口的數(shù)據(jù)總線。

      具體邏輯可以根據(jù)代碼和功能仿真理解。

      設(shè)計(jì)源碼 IP首部校驗(yàn)和

      check sum的計(jì)算步驟可以查看本系列的第二篇博文,此處不贅述。

      // | ===================================================---------------------------===================================================
      // | --------------------------------------------------- 	IP數(shù)據(jù)頭部計(jì)算模塊 	   ---------------------------------------------------
      // | ===================================================---------------------------===================================================
      // | 創(chuàng)建時(shí)間 : 2022-01-14
      // | 完成時(shí)間 : 2022-01-14
      // | 作    者 :Xu Y. B.( 用戶名:在路上,正出發(fā))
      // | 功能說明 :
      // | 			-1- 計(jì)算延遲 6 個(gè)時(shí)鐘周期,欲使用該模塊的結(jié)果,須計(jì)劃好數(shù)據(jù)輸入的時(shí)間
      // | 			-2- 建議發(fā)送前導(dǎo)碼時(shí)就開始計(jì)算
      // |			-3- 與下游模塊交互采用握手機(jī)制
      // |
      // | ================================= 		模塊修改歷史紀(jì)錄 	  =================================
      // | 修改日期:
      // | 修改作者:
      // | 修改注解:
      
      
      
      
      
      
      `timescale 1ns / 1ps
      
      module IP_HEAD_CHECK_SUM_CAL_MDL(
      
      // | ==================================== 模塊輸入輸出端口聲明 ====================================
      input 															I_OPR_CLK,
      input 															I_OPR_RSTN,
      
      input 															I_CAL_EN,//脈沖信號(hào)
      
      // IP 頭部參數(shù)
      input 			[3:0]											I_IP_HEAD_VER,
      input 			[3:0]											I_IP_HEAD_LEN,	
      input 			[7:0]											I_IP_HEAD_TOS,   
      input 			[15:0]											I_IP_HEAD_TOTLEN,
      input 			[15:0]											I_IP_HEAD_ID,
      input 			[2:0]											I_IP_HEAD_FLAG, 
      input 			[12:0]											I_IP_HEAD_OFFSET,
      input 			[7:0]											I_IP_HEAD_TTL,	
      input 			[7:0]											I_IP_HEAD_PROT, 
      input 			[31:0]											I_IP_HEAD_SRC_ADDR,
      input 			[31:0]											I_IP_HEAD_DST_ADDR,
      
      output 			[15:0]											O_IP_HEAD_CHECK_SUM
      );
      
      
      // | ====================================   模塊內(nèi)部參數(shù)聲明   ====================================
      
      // | ====================================   模塊內(nèi)部信號(hào)聲明   ====================================
      reg 			[16:0]											R_ADD1_L1[3:0];
      reg 			[17:0]											R_ADD1_L2[1:0];
      reg 			[18:0]											R_ADD1_L3;
      reg 			[19:0]											R_ADD1_L4;
      reg 			[16:0]											R_ADD2;
      reg 			[15:0]											R_ADD3;
      
      
      // | ====================================   模塊內(nèi)部邏輯設(shè)計(jì)   ====================================
      // ADD1 第一級(jí)
      always @ (posedge I_OPR_CLK)
      begin
      	if(~I_OPR_RSTN)
      	begin
      		R_ADD1_L1[0]<= 17'd0;
              R_ADD1_L1[1]<= 17'd0;
              R_ADD1_L1[2]<= 17'd0;
              R_ADD1_L1[3]<= 17'd0;
      	end
      	else if(I_CAL_EN)
      	begin 
      		R_ADD1_L1[0]<=   {I_IP_HEAD_VER,I_IP_HEAD_LEN,I_IP_HEAD_TOS} + I_IP_HEAD_TOTLEN;  
      		R_ADD1_L1[1]<=   I_IP_HEAD_ID + {I_IP_HEAD_FLAG,I_IP_HEAD_OFFSET};  
      		R_ADD1_L1[2]<=   {I_IP_HEAD_TTL,I_IP_HEAD_PROT} + I_IP_HEAD_SRC_ADDR[31:16];  
      		R_ADD1_L1[3]<=   I_IP_HEAD_SRC_ADDR[15:0] + I_IP_HEAD_DST_ADDR[31:16];  
      	end
      end
      
      // ADD1 第二級(jí)
      always @ (posedge I_OPR_CLK)
      begin
      	if(~I_OPR_RSTN)
      	begin
      		R_ADD1_L2[0]<= 18'd0;
      		R_ADD1_L2[1]<= 18'd0;
      	end
      	else
      	begin
      		R_ADD1_L2[0]<= R_ADD1_L1[0] + R_ADD1_L1[1];
      		R_ADD1_L2[1]<= R_ADD1_L1[2] + R_ADD1_L1[3];
      	end
      end
      
      // ADD1 第三級(jí)
      always @ (posedge I_OPR_CLK)
      begin
      	if(~I_OPR_RSTN)
      	begin
      		R_ADD1_L3<= 19'd0;
      	end
      	else
      	begin
      		R_ADD1_L3<= R_ADD1_L2[0] + R_ADD1_L2[1];
      	end
      end
      
      // ADD1 第四級(jí)
      always @ (posedge I_OPR_CLK)
      begin
      	if(~I_OPR_RSTN)
      	begin
      		R_ADD1_L4<= 20'd0;
      	end
      	else
      	begin
      		R_ADD1_L4<= R_ADD1_L3 + I_IP_HEAD_DST_ADDR[15:0];
      	end
      end
      
      // ADD2 
      always @ (posedge I_OPR_CLK)
      begin
      	if(~I_OPR_RSTN)
      	begin
      		R_ADD2<= 17'd0;
      	end
      	else
      	begin
      		R_ADD2<= R_ADD1_L4[19:16]+ R_ADD1_L4[15:0];
      	end
      end
      
      // ADD3 
      always @ (posedge I_OPR_CLK)
      begin
      	if(~I_OPR_RSTN)
      	begin
      		R_ADD3<= 16'd0;
      	end
      	else
      	begin
      		R_ADD3<= R_ADD2[16]+ R_ADD2[15:0];
      	end
      end
      
      
      assign O_IP_HEAD_CHECK_SUM = ~R_ADD3;
      
      endmodule
      FCS計(jì)算

      以太網(wǎng)的數(shù)據(jù)校驗(yàn)采用的CRC32校驗(yàn)方式。對(duì)于CRC32校驗(yàn)的計(jì)算,有在線生成設(shè)計(jì)源碼的網(wǎng)站可用:

      CRC校驗(yàn)程序在線生成http://crctool.easics.be/

      做如下需改:

      // Copyright (C) 1999-2008 Easics NV.
      // This source file may be used and distributed without restriction
      // provided that this copyright statement is not removed from the file
      // and that any derivative work contains the original copyright notice
      // and the associated disclaimer.
      //
      // THIS SOURCE FILE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS
      // OR IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
      // WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
      //
      // Purpose : synthesizable CRC function
      //   * polynomial: x^32 + x^26 + x^23 + x^22 + x^16 + x^12 + x^11 + x^10 + x^8 + x^7 + x^5 + x^4 + x^2 + x^1 + 1
      //   * data width: 8
      //
      // Info : tools@easics.be
      //        http://www.easics.com
      
      module CRC32_D8 (
      // 輸入輸出端口
      input               I_OPR_CLK,
      input               I_OPR_RSTN,
      
      input               I_CRC_INIT,
      
      input               I_CRC_EN,
      input     [7:0]     I_DATA,
      output    [31:0]    O_CRC_RES
      
      
      );
      // 內(nèi)部信號(hào)
      wire [7:0]  W_DATA;
      reg  [31:0] R_CRC_RES;
      
      genvar GV_8;
      generate
          for(GV_8 = 0;GV_8< 8;GV_8 = GV_8 + 1)
          begin
              assign W_DATA[GV_8] = I_DATA[7-GV_8];
          end
      endgenerate
      
      always @ (posedge I_OPR_CLK)
      begin
          if(~I_OPR_RSTN)
          begin
              R_CRC_RES<= {32{1'b1}};
          end
          else if(I_CRC_INIT)
          begin
             R_CRC_RES<= {32{1'b1}}; 
          end
          else if(I_CRC_EN)
          begin
              R_CRC_RES<= nextCRC32_D8(W_DATA,R_CRC_RES);
          end
      end
      
      genvar GV_32;
      generate
          for(GV_32 = 0;GV_32< 32;GV_32 = GV_32 + 1)
          begin
              assign O_CRC_RES[GV_32] = ~R_CRC_RES[31-GV_32];
          end
      endgenerate
      
      
      // polynomial: x^32 + x^26 + x^23 + x^22 + x^16 + x^12 + x^11 + x^10 + x^8 + x^7 + x^5 + x^4 + x^2 + x^1 + 1
      // data width: 8
      // convention: the first serial bit is D[7]
      function [31:0] nextCRC32_D8;
        input [7:0] Data;
        input [31:0] crc;
        reg [7:0] d;
        reg [31:0] c;
        reg [31:0] newcrc;
        begin
          d = Data;
          c = crc;
          newcrc[0] = d[6] ^ d[0] ^ c[24] ^ c[30];
          newcrc[1] = d[7] ^ d[6] ^ d[1] ^ d[0] ^ c[24] ^ c[25] ^ c[30] ^ c[31];
          newcrc[2] = d[7] ^ d[6] ^ d[2] ^ d[1] ^ d[0] ^ c[24] ^ c[25] ^ c[26] ^ c[30] ^ c[31];
          newcrc[3] = d[7] ^ d[3] ^ d[2] ^ d[1] ^ c[25] ^ c[26] ^ c[27] ^ c[31];
          newcrc[4] = d[6] ^ d[4] ^ d[3] ^ d[2] ^ d[0] ^ c[24] ^ c[26] ^ c[27] ^ c[28] ^ c[30];
          newcrc[5] = d[7] ^ d[6] ^ d[5] ^ d[4] ^ d[3] ^ d[1] ^ d[0] ^ c[24] ^ c[25] ^ c[27] ^ c[28] ^ c[29] ^ c[30] ^ c[31];
          newcrc[6] = d[7] ^ d[6] ^ d[5] ^ d[4] ^ d[2] ^ d[1] ^ c[25] ^ c[26] ^ c[28] ^ c[29] ^ c[30] ^ c[31];
          newcrc[7] = d[7] ^ d[5] ^ d[3] ^ d[2] ^ d[0] ^ c[24] ^ c[26] ^ c[27] ^ c[29] ^ c[31];
          newcrc[8] = d[4] ^ d[3] ^ d[1] ^ d[0] ^ c[0] ^ c[24] ^ c[25] ^ c[27] ^ c[28];
          newcrc[9] = d[5] ^ d[4] ^ d[2] ^ d[1] ^ c[1] ^ c[25] ^ c[26] ^ c[28] ^ c[29];
          newcrc[10] = d[5] ^ d[3] ^ d[2] ^ d[0] ^ c[2] ^ c[24] ^ c[26] ^ c[27] ^ c[29];
          newcrc[11] = d[4] ^ d[3] ^ d[1] ^ d[0] ^ c[3] ^ c[24] ^ c[25] ^ c[27] ^ c[28];
          newcrc[12] = d[6] ^ d[5] ^ d[4] ^ d[2] ^ d[1] ^ d[0] ^ c[4] ^ c[24] ^ c[25] ^ c[26] ^ c[28] ^ c[29] ^ c[30];
          newcrc[13] = d[7] ^ d[6] ^ d[5] ^ d[3] ^ d[2] ^ d[1] ^ c[5] ^ c[25] ^ c[26] ^ c[27] ^ c[29] ^ c[30] ^ c[31];
          newcrc[14] = d[7] ^ d[6] ^ d[4] ^ d[3] ^ d[2] ^ c[6] ^ c[26] ^ c[27] ^ c[28] ^ c[30] ^ c[31];
          newcrc[15] = d[7] ^ d[5] ^ d[4] ^ d[3] ^ c[7] ^ c[27] ^ c[28] ^ c[29] ^ c[31];
          newcrc[16] = d[5] ^ d[4] ^ d[0] ^ c[8] ^ c[24] ^ c[28] ^ c[29];
          newcrc[17] = d[6] ^ d[5] ^ d[1] ^ c[9] ^ c[25] ^ c[29] ^ c[30];
          newcrc[18] = d[7] ^ d[6] ^ d[2] ^ c[10] ^ c[26] ^ c[30] ^ c[31];
          newcrc[19] = d[7] ^ d[3] ^ c[11] ^ c[27] ^ c[31];
          newcrc[20] = d[4] ^ c[12] ^ c[28];
          newcrc[21] = d[5] ^ c[13] ^ c[29];
          newcrc[22] = d[0] ^ c[14] ^ c[24];
          newcrc[23] = d[6] ^ d[1] ^ d[0] ^ c[15] ^ c[24] ^ c[25] ^ c[30];
          newcrc[24] = d[7] ^ d[2] ^ d[1] ^ c[16] ^ c[25] ^ c[26] ^ c[31];
          newcrc[25] = d[3] ^ d[2] ^ c[17] ^ c[26] ^ c[27];
          newcrc[26] = d[6] ^ d[4] ^ d[3] ^ d[0] ^ c[18] ^ c[24] ^ c[27] ^ c[28] ^ c[30];
          newcrc[27] = d[7] ^ d[5] ^ d[4] ^ d[1] ^ c[19] ^ c[25] ^ c[28] ^ c[29] ^ c[31];
          newcrc[28] = d[6] ^ d[5] ^ d[2] ^ c[20] ^ c[26] ^ c[29] ^ c[30];
          newcrc[29] = d[7] ^ d[6] ^ d[3] ^ c[21] ^ c[27] ^ c[30] ^ c[31];
          newcrc[30] = d[7] ^ d[4] ^ c[22] ^ c[28] ^ c[31];
          newcrc[31] = d[5] ^ c[23] ^ c[29];
          nextCRC32_D8 = newcrc;
        end
      endfunction
      
      endmodule
      UDP發(fā)送頂層

      主要是使用狀態(tài)機(jī)控制發(fā)送流程:

      // | ===================================================---------------------------===================================================
      // | --------------------------------------------------- 	  UDP 數(shù)據(jù)發(fā)送模塊 	   ---------------------------------------------------
      // | ===================================================---------------------------===================================================
      // | 創(chuàng)建時(shí)間 : 2022-01-13
      // | 完成時(shí)間 : 2022-01-13
      // | 作    者 :Xu Y. B.( 用戶名:在路上,正出發(fā))
      // | 功能說明 :
      // |			-1- 參數(shù)可配置
      // |			-2- 包含CRC32校驗(yàn)
      // |			-3- 發(fā)出數(shù)據(jù)請(qǐng)求后,須1個(gè)時(shí)鐘周期后給出有效數(shù)據(jù),輸入到此模塊
      // |			-4- IP頭部 固定為 20字節(jié)
      // |			-5- 幀間距長(zhǎng)度 12字節(jié)
      // |
      // | ================================= 		模塊修改歷史紀(jì)錄 	  =================================
      // | 修改日期:
      // | 修改作者:
      // | 修改注解:
      
      
      
      
      
      
      `timescale 1ns / 1ps
      module UDP_TX_MDL #(
      // | ====================================  模塊可配置參數(shù)聲明  ==================================== 
      parameter 			P_FPGA_MAC_ADDR				=				48'h00_00_00_00_00_00,   // FPGA側(cè) MAC地址
      parameter 			P_FPGA_IP_ADDR				=				{8'd0,8'd0,8'd0,8'd0},   // FPGA側(cè) IP地址
      parameter 			P_FPGA_UDP_PORT				=				16'd0, 				     // FPGA側(cè) UDP端口號(hào)
      
      parameter 			P_DST_MAC_ADDR				=				48'h00_00_00_00_00_00,   // 目的側(cè) MAC地址
      parameter 			P_DST_IP_ADDR				=				{8'd0,8'd0,8'd0,8'd0},   // 目的側(cè) IP地址
      parameter 			P_DST_UDP_PORT				=				16'd0 				     // 目的側(cè) UDP端口號(hào)
      )(
      // | ==================================== 模塊輸入輸出端口聲明 ====================================
      // 時(shí)鐘、復(fù)位
      input 															I_CLK_125M,
      input 															I_SYS_RSTN,
      // 發(fā)送 握手信號(hào)
      input 															I_TX_EN,//脈沖信號(hào)
      output  reg 													O_TX_DONE,
      // 數(shù)據(jù)長(zhǎng)度
      input 				[15:0]										I_TX_DATA_LEN,   //一直有效至下一次傳輸開始,
      																				 // 最小數(shù)據(jù)為 1 大為 1472(大值前提是 IP首部長(zhǎng)度 20)
      // 數(shù)據(jù)
      input 				[7:0]										I_TX_DATA,
      output 	reg														O_DATA_REQ,
      // GMII接口
      output 															O_GMII_TX_CLK,
      (*IOB = "TRUE"*)(*MARK_DEBUG = "TRUE"*)
      output  reg 		[7:0]										O_GMII_TXD, //插入I/O緩沖,提高驅(qū)動(dòng)
      (*IOB = "TRUE"*)(*MARK_DEBUG = "TRUE"*)
      output 	reg 													O_GMII_TX_EN //插入I/O緩沖
          );
      // | ====================================   模塊內(nèi)部參數(shù)聲明   ====================================
      // 狀態(tài)編碼
      localparam 			LP_ST_IDLE 					=				8'b0000_0001;
      localparam 			LP_ST_PREAMBLE 				=				8'b0000_0010;
      localparam 			LP_ST_ETH_HEAD 				=				8'b0000_0100;
      localparam 			LP_ST_IP_HEAD				=				8'b0000_1000;
      localparam 			LP_ST_UDP_HEAD 				=				8'b0001_0000;
      localparam 			LP_ST_TX_DATA 				=				8'b0010_0000;
      localparam 			LP_ST_TX_FILL 				=				8'b0100_0000;
      localparam 			LP_ST_FCS 					=				8'b1000_0000;
      // 以太網(wǎng)類型 IP數(shù)據(jù)報(bào)
      localparam 			LP_ETH_TYPE 				= 				16'h0800;//以太網(wǎng) IP數(shù)據(jù)報(bào) 類型
      // 前導(dǎo)碼
      localparam 			LP_ETH_PREAMBLE 			=				8'h55;
      localparam 			LP_ETH_SFD 					=				8'hd5;
      // IP首部參數(shù)
      localparam 			LP_IP_HEAD_VER				=				4'h4;
      localparam 			LP_IP_HEAD_LEN 				=				4'h5;
      localparam 			LP_IP_HEAD_TOS      		=				8'h00;
      localparam 			LP_IP_HEAD_ID 				=				16'h0000;
      localparam 			LP_IP_HEAD_FLAG 			=				3'b0_0_0;
      localparam 			LP_IP_HEAD_OFFSET 			=				13'd0;
      localparam 			LP_IP_HEAD_TTL 				=				8'h40;
      localparam 			LP_IP_HEAD_PROT 			=				8'd17;
      
      // | ====================================   模塊內(nèi)部信號(hào)聲明   ====================================
      // 狀態(tài)信號(hào)
      (*MARK_DEBUG = "TRUE"*)
      reg 				[7:0]										R_CS;
      reg 				[7:0]										R_NS;
      // 計(jì)數(shù)器
      reg 				[2:0]										R_PREAMBLE_CNT;
      reg 				[3:0]										R_ETH_HEAD_CNT;
      reg 				[4:0]										R_IP_HEAD_CNT;
      reg 				[2:0]										R_UDP_HEAD_CNT;
      reg 				[15:0]										R_UDP_DATA_CNT;
      reg 				[4:0]										R_FILL_CNT;
      reg 				[1:0]										R_CRC_CNT;
      reg 				[1:0]										R_CRC_CNT2;
      reg 				[3:0]										R_IFG_CNT;
      // IP首部校驗(yàn)和
      wire 			   [15:0]										W_IP_HEAD_CHECK_SUM;
      wire 			   [15:0]										W_UDP_HEAD_CHECK;
      // CRC32校驗(yàn)?zāi)K
      reg              												R_CRC_EN;
      wire   			    [31:0]    									W_CRC_RES;
      // 數(shù)據(jù)長(zhǎng)度
      wire 				[15:0]										W_UDP_LEN;
      wire 				[15:0]										W_IP_LEN;
      // 數(shù)據(jù)發(fā)送
      reg 															R_GMII_TX_EN;
      reg 				[7:0]										R_GMII_TX_DATA;
      
      reg 															R_CRC_ST;
      
      reg 															R_IFG_FLAG;
      
      // | ====================================   模塊內(nèi)部邏輯設(shè)計(jì)   ====================================
      assign 		W_UDP_LEN 		= 		I_TX_DATA_LEN + 16'd8;
      assign 		W_IP_LEN  		= 		W_UDP_LEN + 16'd20;
      assign 		W_UDP_HEAD_CHECK=		16'd0;
      assign 		O_GMII_TX_CLK   = 		I_CLK_125M;
      always @ (posedge I_CLK_125M)
      begin
      	if(~I_SYS_RSTN)
      	begin
      		R_CS<= LP_ST_IDLE;
      	end
      	else
      	begin
      		R_CS<= R_NS;
      	end
      end
      
      always @ (*)
      begin
      	if(~I_SYS_RSTN)
      	begin
      		R_NS = LP_ST_IDLE;
      	end
      	else
      	begin
      		case(R_CS)
      			LP_ST_IDLE:
      			begin
      				if(I_TX_EN)
      				begin
      					R_NS = LP_ST_PREAMBLE;
      				end
      				else
      				begin
      					R_NS = LP_ST_IDLE;
      				end
      			end 		
      			LP_ST_PREAMBLE:
      			begin
      				if(R_PREAMBLE_CNT == 3'd7)
      				begin
      					R_NS = LP_ST_ETH_HEAD;
      				end
      				else
      				begin
      					R_NS = LP_ST_PREAMBLE;
      				end
      			end 
      			LP_ST_ETH_HEAD:
      			begin
      				if(R_ETH_HEAD_CNT == 4'd13)
      				begin
      					R_NS = LP_ST_IP_HEAD;
      				end
      				else
      				begin
      					R_NS = LP_ST_ETH_HEAD;
      				end
      			end 
      			LP_ST_IP_HEAD:
      			begin
      				if(R_IP_HEAD_CNT == 5'd19)
      				begin
      					R_NS = LP_ST_UDP_HEAD;
      				end
      				else
      				begin
      					R_NS = LP_ST_IP_HEAD;
      				end
      			end	
      			LP_ST_UDP_HEAD:
      			begin
      				if(R_UDP_HEAD_CNT == 3'd7)
      				begin
      					R_NS = LP_ST_TX_DATA;
      				end
      				else
      				begin
      					R_NS = LP_ST_UDP_HEAD;
      				end
      			end 
      			LP_ST_TX_DATA:
      			begin
      				if((I_TX_DATA_LEN< 16'd18) && (R_UDP_DATA_CNT == I_TX_DATA_LEN - 1'b1))
      				begin
      					R_NS = LP_ST_TX_FILL;
      				end
      				else if(R_UDP_DATA_CNT == I_TX_DATA_LEN - 1'b1)
      				begin
      					R_NS = LP_ST_FCS;
      				end
      				else
      				begin
      					R_NS = LP_ST_TX_DATA;
      				end
      			end 	
      			LP_ST_TX_FILL:
      			begin
      				if(R_FILL_CNT == (5'd17 - I_TX_DATA_LEN[4:0]))
      				begin
      					R_NS = LP_ST_FCS;
      				end
      				else
      				begin
      					R_NS = LP_ST_TX_FILL;
      				end
      			end 	
      			LP_ST_FCS:
      			begin
      				if(R_CRC_CNT == 2'd3)
      				begin
      					R_NS = LP_ST_IDLE;
      				end
      				else
      				begin
      					R_NS = LP_ST_FCS;
      				end
      			end
      			default:
      			begin
      				R_NS = LP_ST_IDLE;
      			end 					
      		endcase
      	end
      end
      // 以太網(wǎng)數(shù)據(jù)發(fā)送
      always @ (posedge I_CLK_125M)
      begin
      	if(~I_SYS_RSTN)
      	begin
      		R_PREAMBLE_CNT<= 3'd0;
      		R_ETH_HEAD_CNT<= 4'd0;
      		R_IP_HEAD_CNT<= 5'd0;
      		R_UDP_HEAD_CNT<= 3'd0;
      		R_UDP_DATA_CNT<= 16'd0;
      		R_FILL_CNT<= 5'd0;
      		R_CRC_CNT<= 2'd0;
      
      		R_GMII_TX_EN<= 1'b0;
      		R_GMII_TX_DATA<= 8'd0;
      	end
      	else
      	begin
      		case(R_CS)
      			LP_ST_IDLE:
      			begin
      				R_PREAMBLE_CNT<= 3'd0;
      				R_ETH_HEAD_CNT<= 4'd0;
      				R_IP_HEAD_CNT<= 5'd0;
      				R_UDP_HEAD_CNT<= 3'd0;
      				R_UDP_DATA_CNT<= 16'd0;
      				R_FILL_CNT<= 5'd0;
      				R_CRC_CNT<= 2'd0;
      
      				R_GMII_TX_EN<= 1'b0;
      				R_GMII_TX_DATA<= 8'd0;
      			end
      			LP_ST_PREAMBLE:
      			begin
      				R_PREAMBLE_CNT<= R_PREAMBLE_CNT + 1;
      				R_GMII_TX_EN<= 1'b1;
      				if(R_PREAMBLE_CNT<= 3'd6)
      					R_GMII_TX_DATA<= 8'h55;
      				else
      					R_GMII_TX_DATA<= 8'hd5;
      			end
      			LP_ST_ETH_HEAD:
      			begin
      				R_ETH_HEAD_CNT<= R_ETH_HEAD_CNT + 1;
      				case(R_ETH_HEAD_CNT)
      					4'd0: R_GMII_TX_DATA<= P_DST_MAC_ADDR[47:40];
      					4'd1: R_GMII_TX_DATA<= P_DST_MAC_ADDR[39:32];
      					4'd2: R_GMII_TX_DATA<= P_DST_MAC_ADDR[31:24];
      					4'd3: R_GMII_TX_DATA<= P_DST_MAC_ADDR[23:16];
      					4'd4: R_GMII_TX_DATA<= P_DST_MAC_ADDR[15:8];
      					4'd5: R_GMII_TX_DATA<= P_DST_MAC_ADDR[7:0];
      					4'd6: R_GMII_TX_DATA<= P_FPGA_MAC_ADDR[47:40];
      					4'd7: R_GMII_TX_DATA<= P_FPGA_MAC_ADDR[39:32];
      					4'd8: R_GMII_TX_DATA<= P_FPGA_MAC_ADDR[31:24];
      					4'd9: R_GMII_TX_DATA<= P_FPGA_MAC_ADDR[23:16];
      					4'd10:R_GMII_TX_DATA<= P_FPGA_MAC_ADDR[15:8];
      					4'd11:R_GMII_TX_DATA<= P_FPGA_MAC_ADDR[7:0];
      					4'd12:R_GMII_TX_DATA<= LP_ETH_TYPE[15:8];
      					4'd13:R_GMII_TX_DATA<= LP_ETH_TYPE[7:0];
      					default:R_GMII_TX_DATA<= 8'h00;
      				endcase
      			end
      			LP_ST_IP_HEAD:
      			begin
      				R_IP_HEAD_CNT<= R_IP_HEAD_CNT + 1;
      				case(R_IP_HEAD_CNT)
      					5'd0:  R_GMII_TX_DATA<= {LP_IP_HEAD_VER,LP_IP_HEAD_LEN};
      					5'd1:  R_GMII_TX_DATA<= LP_IP_HEAD_TOS;
      					5'd2:  R_GMII_TX_DATA<= W_IP_LEN[15:8];
      					5'd3:  R_GMII_TX_DATA<= W_IP_LEN[7:0];
      					5'd4:  R_GMII_TX_DATA<= LP_IP_HEAD_ID[15:8];
      					5'd5:  R_GMII_TX_DATA<= LP_IP_HEAD_ID[7:0];
      					5'd6:  R_GMII_TX_DATA<= {LP_IP_HEAD_FLAG,LP_IP_HEAD_OFFSET[12:8]};
      					5'd7:  R_GMII_TX_DATA<= LP_IP_HEAD_OFFSET[7:0];
      					5'd8:  R_GMII_TX_DATA<= LP_IP_HEAD_TTL;
      					5'd9:  R_GMII_TX_DATA<= LP_IP_HEAD_PROT;
      					5'd10: R_GMII_TX_DATA<= W_IP_HEAD_CHECK_SUM[15:8];
      					5'd11: R_GMII_TX_DATA<= W_IP_HEAD_CHECK_SUM[7:0];
      					5'd12: R_GMII_TX_DATA<= P_FPGA_IP_ADDR[31:24];
      					5'd13: R_GMII_TX_DATA<= P_FPGA_IP_ADDR[23:16];
      					5'd14: R_GMII_TX_DATA<= P_FPGA_IP_ADDR[15:8];
      					5'd15: R_GMII_TX_DATA<= P_FPGA_IP_ADDR[7:0];
      					5'd16: R_GMII_TX_DATA<= P_DST_IP_ADDR[31:24];
      					5'd17: R_GMII_TX_DATA<= P_DST_IP_ADDR[23:16];
      					5'd18: R_GMII_TX_DATA<= P_DST_IP_ADDR[15:8];
      					5'd19: R_GMII_TX_DATA<= P_DST_IP_ADDR[7:0];
      					default: R_GMII_TX_DATA<= 8'd0;
      				endcase
      			end
      			LP_ST_UDP_HEAD:
      			begin
      				R_UDP_HEAD_CNT<= R_UDP_HEAD_CNT + 1;
      				case(R_UDP_HEAD_CNT)
      					3'd0: R_GMII_TX_DATA<= P_FPGA_UDP_PORT[15:8];
      					3'd1: R_GMII_TX_DATA<= P_FPGA_UDP_PORT[7:0];
      					3'd2: R_GMII_TX_DATA<= P_DST_UDP_PORT[15:8];
      					3'd3: R_GMII_TX_DATA<= P_DST_UDP_PORT[7:0];
      					3'd4: R_GMII_TX_DATA<= W_UDP_LEN[15:8];
      					3'd5: R_GMII_TX_DATA<= W_UDP_LEN[7:0];
      					3'd6: R_GMII_TX_DATA<= W_UDP_HEAD_CHECK[15:8];
      					3'd7: R_GMII_TX_DATA<= W_UDP_HEAD_CHECK[7:0];
      					default: R_GMII_TX_DATA<= 8'd0;
      				endcase
      			end
      			LP_ST_TX_DATA:
      			begin
      				R_UDP_DATA_CNT<= R_UDP_DATA_CNT + 1;
      				R_GMII_TX_DATA<= I_TX_DATA;
      			end
      			LP_ST_TX_FILL:
      			begin
      				R_FILL_CNT<= R_FILL_CNT + 1;
      				R_GMII_TX_DATA<= 8'd0;
      			end
      			LP_ST_FCS:
      			begin
      				R_CRC_CNT<= R_CRC_CNT + 1;
      				R_GMII_TX_DATA<= 8'd0;
      			end
      			default:
      			begin
      				R_PREAMBLE_CNT<= 3'd0;
      				R_ETH_HEAD_CNT<= 4'd0;
      				R_IP_HEAD_CNT<= 5'd0;
      				R_UDP_HEAD_CNT<= 3'd0;
      				R_UDP_DATA_CNT<= 16'd0;
      				R_FILL_CNT<= 5'd0;
      				R_CRC_CNT<= 2'd0;
      
      				R_GMII_TX_EN<= 1'b0;
      				R_GMII_TX_DATA<= 8'd0;
      			end
      		endcase
      	end
      end
      
      always @ (posedge I_CLK_125M)
      begin
      	if(~I_SYS_RSTN)
      	begin
      		O_DATA_REQ<= 1'b0;
      	end
      	else
      	begin
      		if((|(LP_ST_UDP_HEAD & R_CS)) && R_UDP_HEAD_CNT == 3'd6)
      		begin
      			O_DATA_REQ<= 1'b1;
      		end
      		else if(I_TX_DATA_LEN == 16'd1)
      		begin
      			O_DATA_REQ<= 1'b0;
      		end
      		else if((R_UDP_DATA_CNT == I_TX_DATA_LEN - 16'd2) && (I_TX_DATA_LEN >16'd1) && (|(LP_ST_TX_DATA & R_CS))) 
      		begin
      			O_DATA_REQ<= 1'b0;
      		end
      	end
      end
      
      always @ (posedge I_CLK_125M)
      begin
      	if(~I_SYS_RSTN)
      	begin
      		R_CRC_EN<= 1'b0;
      	end
      	else if(R_CS[2])
      	begin
      		R_CRC_EN<= 1'b1;
      	end
      	else if(R_CS[7])
      	begin
      		R_CRC_EN<= 1'b0;
      	end
      end
      
      always @ (posedge I_CLK_125M)
      begin
      	if(~I_SYS_RSTN)
      	begin
      		R_CRC_ST<= 1'b0;
      	end
      	else
      	begin
      		R_CRC_ST<= R_CS[7];
      	end
      end
      
      always @ (posedge I_CLK_125M)
      begin
      	if(~I_SYS_RSTN)
      	begin
      		O_GMII_TXD<= 8'd0;
      		O_GMII_TX_EN<= 1'b0;
      	end
      	else if(~R_CRC_ST & R_GMII_TX_EN)
      	begin
      		O_GMII_TXD<= R_GMII_TX_DATA;
      		O_GMII_TX_EN<= 1'b1;	
      	end
      	else if(R_CRC_ST)
      	begin
      		O_GMII_TX_EN<= 1'b1;
      		case(R_CRC_CNT2)
      			2'd0:O_GMII_TXD<= W_CRC_RES[7:0];
      			2'd1:O_GMII_TXD<= W_CRC_RES[15:8];
      			2'd2:O_GMII_TXD<= W_CRC_RES[23:16];
      			2'd3:O_GMII_TXD<= W_CRC_RES[31:24];
      			default:O_GMII_TXD<= 8'h00;
      		endcase
      	end
      	else
      	begin
      		O_GMII_TXD<= 8'd0;
      		O_GMII_TX_EN<= 1'b0;	
      	end
      end
      
      always @ (posedge I_CLK_125M)
      begin
      	if(~I_SYS_RSTN)
      	begin
      		R_CRC_CNT2<= 2'd0;
      	end
      	else if(R_CRC_ST)
      	begin
      		R_CRC_CNT2<= R_CRC_CNT2 + 1;
      	end
      	else
      	begin
      		R_CRC_CNT2<= 2'd0;
      	end
      end
      
      always @ (posedge I_CLK_125M)
      begin
      	if(~I_SYS_RSTN)
      	begin
      		R_IFG_FLAG<= 1'b0;
      		R_IFG_CNT<= 4'd0;
      		O_TX_DONE<= 1'b0;
      	end
      	else
      	begin
      		case(R_IFG_FLAG)
      			0:
      			begin
      				R_IFG_CNT<= 4'd0;
      				O_TX_DONE<= 1'b0;
      
      				if(R_CRC_ST && (R_CRC_CNT2 == 2'd3))
      				begin
      					R_IFG_FLAG<= 1'b1;
      				end
      				else
      				begin
      					R_IFG_FLAG<= 1'b0;
      				end
      			end
      			1:
      			begin
      				if(R_IFG_CNT == 4'd12)
      				begin
      					O_TX_DONE<= 1'b1;
      					R_IFG_CNT<= 4'd0;
      					R_IFG_FLAG<= 1'b0;
      				end
      				else
      				begin
      					O_TX_DONE<= 1'b0;
      					R_IFG_CNT<= R_IFG_CNT + 1;
      					R_IFG_FLAG<= 1'b1;
      				end
      			end
      			default:
      			begin
      				R_IFG_FLAG<= 1'b0;
      			end
      		endcase
      	end
      end
      
      // | ====================================   模塊內(nèi)部模塊例化   ====================================
      // CRC32 校驗(yàn)
      CRC32_D8 INST_CRC32_D8
      	(
      		.I_OPR_CLK  (I_CLK_125M),
      		.I_OPR_RSTN (I_SYS_RSTN),
      		.I_CRC_INIT (R_CS[0] & I_TX_EN),
      		.I_CRC_EN   (R_CRC_EN),
      		.I_DATA     (R_GMII_TX_DATA),
      		.O_CRC_RES  (W_CRC_RES)
      	);
      
      
      // IP首部校驗(yàn)?zāi)K
      IP_HEAD_CHECK_SUM_CAL_MDL INST_IP_HEAD_CHECK_SUM_CAL_MDL
      	(
      		.I_OPR_CLK           (I_CLK_125M),
      		.I_OPR_RSTN          (I_SYS_RSTN),
      		.I_CAL_EN            (I_TX_EN),
      		.I_IP_HEAD_VER       (LP_IP_HEAD_VER),
      		.I_IP_HEAD_LEN       (LP_IP_HEAD_LEN),
      		.I_IP_HEAD_TOS       (LP_IP_HEAD_TOS),
      		.I_IP_HEAD_TOTLEN    (W_IP_LEN),
      		.I_IP_HEAD_ID        (LP_IP_HEAD_ID),
      		.I_IP_HEAD_FLAG      (LP_IP_HEAD_FLAG),
      		.I_IP_HEAD_OFFSET    (LP_IP_HEAD_OFFSET),
      		.I_IP_HEAD_TTL       (LP_IP_HEAD_TTL),
      		.I_IP_HEAD_PROT      (LP_IP_HEAD_PROT),
      		.I_IP_HEAD_SRC_ADDR  (P_FPGA_IP_ADDR),
      		.I_IP_HEAD_DST_ADDR  (P_DST_IP_ADDR),
      
      		.O_IP_HEAD_CHECK_SUM (W_IP_HEAD_CHECK_SUM)
      	);
      
      endmodule
      仿真測(cè)試 TEST BENCH
      // | ===================================================---------------------------===================================================
      // | ---------------------------------------------------   UDP 數(shù)據(jù)發(fā)送模塊測(cè)試    ---------------------------------------------------
      // | ===================================================---------------------------===================================================
      // | 創(chuàng)建時(shí)間 : 2022-01-15
      // | 完成時(shí)間 : 2022-01-15
      // | 作    者 :Xu Y. B.( 用戶名:在路上,正出發(fā))
      // | 功能說明 :
      // | 			-1- 
      // | 			-2- 
      // |
      // | ================================= 		模塊修改歷史紀(jì)錄 	  =================================
      // | 修改日期:
      // | 修改作者:
      // | 修改注解:
      
      `timescale 1ns / 1ps
      
      
      
      module TB_UDP_TX_MDL();
      // | ====================================  模塊可配置參數(shù)聲明  ==================================== 
      parameter 			P_FPGA_MAC_ADDR				=				48'h00_0a_35_01_fe_c0;   // FPGA側(cè) MAC地址
      parameter 			P_FPGA_IP_ADDR				=				{8'd192,8'd168,8'd8,8'd3};   // FPGA側(cè) IP地址
      parameter 			P_FPGA_UDP_PORT				=				16'd6001; 				     // FPGA側(cè) UDP端口號(hào)
      
      parameter 			P_DST_MAC_ADDR				=				48'hC8_5B_76_DD_0B_38;   // 目的側(cè) MAC地址
      parameter 			P_DST_IP_ADDR				=				{8'd192,8'd168,8'd8,8'd2};   // 目的側(cè) IP地址
      parameter 			P_DST_UDP_PORT				=				16'd6002; 				     // 目的側(cè) UDP端口號(hào)
      
      // | ==================================== 模塊輸入輸出端口聲明 ====================================
      // 時(shí)鐘、復(fù)位
      reg 															I_CLK_125M;
      reg 															I_SYS_RSTN;
      // 發(fā)送 握手信號(hào)
      reg 															I_TX_EN;//脈沖信號(hào)
      wire        													O_TX_DONE;
      // 數(shù)據(jù)長(zhǎng)度
      reg 				[15:0]										I_TX_DATA_LEN;   //一直有效至下一次傳輸開始,
      																				 // 最小數(shù)據(jù)為 1 大為 1472(大值前提是 IP首部長(zhǎng)度 20)
      // 數(shù)據(jù)
      reg 				[7:0]										I_TX_DATA;
      wire    														O_DATA_REQ;
      // GMII接口
      wire 															O_GMII_TX_CLK;
      (*IOB = "TRUE"*)
      wire     		    [7:0]										O_GMII_TXD; //插入I/O緩沖,提高驅(qū)動(dòng)
      (*IOB = "TRUE"*)
      wire     													    O_GMII_TX_EN; //插入I/O緩沖
      // | ====================================     產(chǎn)生測(cè)試激勵(lì) 	   ====================================
      initial I_CLK_125M = 1'b0;
      always #4 I_CLK_125M = ~I_CLK_125M;
      
      initial
      begin
      	I_SYS_RSTN = 0;
      	I_TX_EN = 0;
      	I_TX_DATA_LEN = 16'd0;
      	I_TX_DATA = 8'd0;
      
      	#124;
      	I_SYS_RSTN = 1;
      	#29;
      	@(posedge I_CLK_125M)
      	I_TX_EN<= 1'b1;
      	I_TX_DATA_LEN<= 16'd1000;
      	@(posedge I_CLK_125M)
      	I_TX_EN<= 1'b0;
      	@(posedge O_DATA_REQ)
      	repeat(1000)
      	begin
      		@(posedge I_CLK_125M)
      		I_TX_DATA<= I_TX_DATA + 1; 
      	end
      
      	@(posedge O_TX_DONE);
      	#2000;
      
      	@(posedge I_CLK_125M)
      	I_TX_EN<= 1'b1;
      	I_TX_DATA_LEN<= 16'd10;
      	@(posedge I_CLK_125M)
      	I_TX_EN<= 1'b0;
      	@(posedge O_DATA_REQ)
      	repeat(10)
      	begin
      		@(posedge I_CLK_125M)
      		I_TX_DATA<= I_TX_DATA + 1; 
      	end
      
      	@(posedge O_TX_DONE);
      	#2000;
      	$finish;
      
      end
      
      UDP_TX_MDL #(
      		.P_FPGA_MAC_ADDR(P_FPGA_MAC_ADDR),
      		.P_FPGA_IP_ADDR (P_FPGA_IP_ADDR),
      		.P_FPGA_UDP_PORT(P_FPGA_UDP_PORT),
      		.P_DST_MAC_ADDR (P_DST_MAC_ADDR),
      		.P_DST_IP_ADDR  (P_DST_IP_ADDR),
      		.P_DST_UDP_PORT (P_DST_UDP_PORT)
      	) INST_UDP_TX_MDL (
      		.I_CLK_125M    (I_CLK_125M),
      		.I_SYS_RSTN    (I_SYS_RSTN),
      		.I_TX_EN       (I_TX_EN),
      		.O_TX_DONE     (O_TX_DONE),
      		.I_TX_DATA_LEN (I_TX_DATA_LEN),
      		.I_TX_DATA     (I_TX_DATA),
      		.O_DATA_REQ    (O_DATA_REQ),
      		.O_GMII_TX_CLK (O_GMII_TX_CLK),
      		.O_GMII_TXD    (O_GMII_TXD),
      		.O_GMII_TX_EN  (O_GMII_TX_EN)
      	);
      
      endmodule
      仿真結(jié)果


      有問題可以評(píng)論區(qū)留言~

      你是否還在尋找穩(wěn)定的海外服務(wù)器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機(jī)房具備T級(jí)流量清洗系統(tǒng)配攻擊溯源,準(zhǔn)確流量調(diào)度確保服務(wù)器高可用性,企業(yè)級(jí)服務(wù)器適合批量采購(gòu),新人活動(dòng)首月15元起,快前往官網(wǎng)查看詳情吧


      分享名稱:基于FPGA的UDP通信(五)-創(chuàng)新互聯(lián)
      URL地址:http://www.ef60e0e.cn/article/dpgjps.html
      99热在线精品一区二区三区_国产伦精品一区二区三区女破破_亚洲一区二区三区无码_精品国产欧美日韩另类一区
      1. <ul id="0c1fb"></ul>

        <noscript id="0c1fb"><video id="0c1fb"></video></noscript>
        <noscript id="0c1fb"><listing id="0c1fb"><thead id="0c1fb"></thead></listing></noscript>

        苏尼特右旗| 曲阳县| 鄂托克旗| 秀山| 密山市| 思茅市| 沛县| 雷波县| 永胜县| 桃园市| 建湖县| 绍兴县| 武义县| 无锡市| 安阳市| 松溪县| 罗源县| 崇礼县| 东乌珠穆沁旗| 娱乐| 长兴县| 陵水| 海淀区| 宜城市| 贺州市| 渑池县| 渝北区| 安多县| 凌海市| 泸水县| 岗巴县| 家居| 成安县| 阳山县| 察隅县| 荥经县| 常熟市| 自治县| 嘉祥县| 江陵县| 嘉义县|