IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 网络协议 -> 仿真通过的UDP和IP发送打包 -> 正文阅读

[网络协议]仿真通过的UDP和IP发送打包

module udp_tx_pack_tb ;

reg rst = 0 ,clk = 0 ;
always #5 clk = ~clk ;

initial begin 
$dumpfile("test_udp_tx_pack.vd");
$dumpvars;
rst = 1;
@(posedge clk) ;
@(posedge clk) ;
rst = 0; 
@(posedge clk) ;
end 



wire [31:0]src_ip ={8'd192,8'd168,8'd2,8'd4} ;
wire [31:0]dst_ip ={8'd192,8'd168,8'd2,8'd3} ;

wire [15:0] src_port = 16'd1234 ;
wire [15:0] dst_port = 16'hcdef ;


wire [15:0]test_len = 8;


reg [31:0]  c;always @(posedge clk) if (rst) c<=0; else c<=c+1; // system counter for debug  

udp_ip_pack  udp_ip_pack (
		  .clk(clk),
		  .rst(rst),
		  .s_src_ip(src_ip),
		  .s_dst_ip(dst_ip),
		  .s_src_port(src_port),
		  .s_dst_port(dst_port), 
		  .s_tx_len(test_len),
		  .s_tx_start(~s_tx_busy ),
		  .s_tx_busy (s_tx_busy),
		  .s_tx_dat(c[7:0]),
		  .s_ip_type( c[7:0] ) ,
		  .s_ip_id( c[15:0] ),  
		 
 		  .m_ip_tx_valid() , 
		  .m_ip_tx_busy  (1'b0) ,  
		  .m_ip_tx_data	()	
		 );
		 
		  


endmodule



		 

module udp_ip_pack (
		 input clk,rst,
		 input [31:0] s_src_ip,s_dst_ip,
		 input [15:0] s_src_port,s_dst_port, s_tx_len,
		 input s_tx_start,
		 output   s_tx_busy ,
		 input [7:0] s_tx_dat,
		 input [7:0] s_ip_type ,
		 input [15:0] s_ip_id,  
		 
 		 output    m_ip_tx_valid , 
		 input m_ip_tx_busy   ,  
		 output   [7:0] m_ip_tx_data		
		 );

wire [31:0] src_ip,dst_ip;
wire [7:0] udp_tx_dat ;
wire [15:0] udp_tx_len ; 
 
udp_pack udp_pack (
		 .clk(clk),
		 .rst(rst ),
		 .s_src_ip(s_src_ip ),
		 .s_dst_ip( s_dst_ip),
		 .s_src_port( s_src_port),
		 .s_dst_port( s_dst_port), 
		 .s_tx_len(s_tx_len ),
		 .s_tx_start(s_tx_start),
		 .s_tx_busy (s_tx_busy),
		 .s_tx_dat( s_tx_dat ),
		   
		 .m_tx_len (udp_tx_len),
		 .m_pack_valid(udp_pack_valid),
		 .m_data_ready (ip_data_ack),
		 .m_tx_dat (udp_tx_dat),
		 .m_src_ip(src_ip),
		 .m_dst_ip(dst_ip) 
		 );


ip_pack  ip_pack (

.clk(clk),
.rst(rst),
.s_ip_TTL(8'd64),
.s_ip_type(s_ip_type) ,
.s_ip_id(s_ip_id), 
.s_ip_src(src_ip),
.s_ip_dst(dst_ip) , 
.s_ip_pack_valid ( udp_pack_valid),
.s_ip_pack_len (udp_tx_len),
.s_ip_data_ack(ip_data_ack),
.s_ip_data( udp_tx_dat) ,
		  
.m_ip_tx_valid ( m_ip_tx_valid),
.m_ip_tx_busy  ( m_ip_tx_busy)  ,  
.m_ip_tx_data  ( m_ip_tx_data )		 

);
 
endmodule 



module udp_pack (
		 input clk,rst,
		 input [31:0] s_src_ip,s_dst_ip,
		 input [15:0] s_src_port,s_dst_port, s_tx_len,
		 input s_tx_start,
		 output reg s_tx_busy ,
		 input [7:0] s_tx_dat,
		 
		 output reg [15:0]  m_tx_len ,
		 output reg m_pack_valid,
		 input m_data_ready ,
		 output[7:0] m_tx_dat ,
		 output reg  [31:0] m_src_ip,m_dst_ip
		 );
		 
		 reg [11:0] wr_addr,wr_addr_end ,rd_addr_end;
		 reg [7:0] wr_data;
		 reg wr_req;
		 reg wr_en ;
		 reg [11:0] rd_addr ;
		 reg [15:0]  st,st2 ; 
		 reg [11:0] wr_cntr ;
		 reg [15:0] src_port_reg ,dst_port_reg , tx_len_reg   ;
		 always @ (posedge clk) if (rst)   {src_port_reg ,dst_port_reg   }<=0;else if (st==100&s_tx_start) {src_port_reg ,dst_port_reg    } <={ s_src_port,s_dst_port };
		 always @ (posedge clk) if (rst)   wr_addr_end<=0; else if (st==100&s_tx_start) wr_addr_end <= s_tx_len + 6;
	         always @ ( posedge clk ) if (rst)   rd_addr_end<=0; else if (st==100&s_tx_start) rd_addr_end <=  s_tx_len + 7; 


		 always @(posedge clk) if (st==100&s_tx_start){m_src_ip,m_dst_ip}<={s_src_ip,s_dst_ip};		 
		 always @ (posedge clk) if (rst)st<=0;else  case (st)
		 0:st<=100;
		 100: if (s_tx_start)st<= 200;
		 200: if (wr_addr == wr_addr_end ) st <= 300 ;
		 300,301,302,303,304,305,306,307:st<=st+1;
		 308: st<=400;// tell st2 can now pick this data
		 400: st<=500;
		 500: if (rd_addr==10 && st2==400) st<=600;
		 600: st<=100; // ok , free now 
		 default st<=0; 
		 endcase 
		 
		 reg [15:0] chksum = 0 ;
		 always @(posedge clk) if (rst) chksum<=0; else case (st)
		 0,100:		 chksum <= 0;
		 200,300,301,302,303,304,305,306,307: chksum<=chksum+wr_data ;
		 endcase 
		
		 always @(posedge clk) if (rst) s_tx_busy<=0;else case(st)200:s_tx_busy<=1;600:s_tx_busy<=0;endcase

		 always @(posedge clk)case (st)
			100:begin  wr_en<=1;wr_data<= s_tx_dat; wr_addr<= 8; end 
			200:begin  wr_en<=1;wr_data<= s_tx_dat; wr_addr<=wr_addr+1; end
			301:begin  wr_en<=1;wr_data<= src_port_reg[7:0]; wr_addr<=0 ; end
			300:begin  wr_en<=1;wr_data<= src_port_reg[15:8]; wr_addr<=1 ; end
			303:begin  wr_en<=1;wr_data<= dst_port_reg[7:0]; wr_addr<=2 ; end
			302:begin  wr_en<=1;wr_data<= dst_port_reg[15:8]; wr_addr<=3 ; end
			304:begin  wr_en<=1;wr_data<= 8; wr_addr<=4 ; end
			305:begin  wr_en<=1;wr_data<= 0; wr_addr<=5 ; end
			307:begin  wr_en<=1;wr_data<= chksum[7:0]; wr_addr<=6 ; end
			306:begin  wr_en<=1;wr_data<= chksum[15:8]; wr_addr<=7 ; end
			default begin  wr_en<=0;wr_data<=0 ; wr_addr<= 0; end
		endcase
		
		always@(posedge clk) if (rst)st2<=0;else case (st2)		
		0:st2<=100;
		100:if (st==400)st2<=200;
		200:if (m_data_ready==1) st2<=400;
		400:if (rd_addr == rd_addr_end) st2<=500 ;
		500:st2<=600;
		600:st2<=100;
		default st2<=0;
		endcase		

	        always @ ( posedge clk ) if (rst)   m_tx_len<=0; else if (st2==100) m_tx_len <=  rd_addr_end + 1; 
		always @(posedge clk) if (rst)m_pack_valid<=0; else  case (st2) 200:m_pack_valid<=1; 400:m_pack_valid<=0; endcase 		

	
 
		
		always @ ( posedge clk ) case (st2)400: if (m_data_ready & (rd_addr != rd_addr_end)) rd_addr<=rd_addr+1;200: if(m_data_ready==1)  rd_addr<=1;default rd_addr<=0;endcase 

		wire [7:0] rd_data ; assign  m_tx_dat = rd_data;
 
		ram2port #( .DWIDTH(8),.AWIDTH(12))ram2port_i(.clk(clk),.wr_en(wr_en),.wr_addr(wr_addr) ,
			.rd_addr(rd_addr) ,.wr_data(wr_data),.rd_data(rd_data)  );

endmodule 
			

module ram2port
#(
    parameter DWIDTH=32,
    parameter AWIDTH=9
)
(
    input clk,
    input wr_en,
    input [AWIDTH-1:0] wr_addr ,
    input [AWIDTH-1:0] rd_addr ,
    input [DWIDTH-1:0] wr_data,
    output reg [DWIDTH-1:0] rd_data
 );


reg [DWIDTH-1:0] ram [(1<<AWIDTH)-1:0];
integer 	    i;
initial begin
    for(i=0;i<(1<<AWIDTH);i=i+1)
        ram[i] <= {DWIDTH{1'b0}};
    rd_data <= 0;
end

always @ (posedge clk) if (wr_en) ram[wr_addr]<=wr_data;
always @ (posedge clk)  rd_data <= ram[rd_addr] ;
endmodule 
  

		module ip_pack (
		 input clk,rst,
		 input [7:0] s_ip_TTL,
		 input [7:0] s_ip_type ,
		 input [15:0] s_ip_id, 
		 input [31:0]s_ip_src,s_ip_dst ,
		 
		 input s_ip_pack_valid ,
		 input [15:0] s_ip_pack_len , 
		 output reg s_ip_data_ack,
		 input [7:0]  s_ip_data ,
		  
		 output reg  m_ip_tx_valid , 
		 input m_ip_tx_busy   , // 平时必须保持busy是0
		 output reg [7:0] m_ip_tx_data		 
		 );
		  
		localparam ip_version    = 4'h4     ;  //ipv4
		localparam header_len    = 4'h5     ;  //header length
		  wire [15:0] checksum ;

 ip_chksum_gen ip_chksum_gen (
		   .clk(clk ) ,
		   .rst(rst ) ,
		   .valid( 1'b1) ,
		   .ready ( ) ,
		   .in0({ip_version, header_len,8'b0}  ) ,//0
		   .in1( s_ip_pack_len) , //1
		   .in2(s_ip_id ) ,//2
		   .in3( 16'h4000 ) ,  //3
		   .in4( {s_ip_TTL,s_ip_type} ) , //4
		   .in5( 16'h0 ) ,//5
		   .in6(s_ip_src[31:16] ) ,//6
		   .in7(s_ip_src[15:0] ) ,//7
		   .in8(s_ip_dst[31:16]  ) ,//8
		   .in9(s_ip_dst[15:0]  ) ,//9 
		   .checksum(checksum)
		 ); 
		 
 reg [7:0] wr_st ;	 
 reg [15:0] cr_cntr ;always @ (posedge clk )case (wr_st) 200: cr_cntr <=cr_cntr+1 ;default cr_cntr<=1;endcase 
 reg [15:0] ip_pack_lenr ;always @ (posedge clk )case (wr_st) 100: ip_pack_lenr <=s_ip_pack_len[15:0] ; endcase

		 always @ (posedge clk) if (rst) wr_st<=0;   else case (wr_st)
		 0: if (s_ip_pack_valid & ~m_ip_tx_busy )  wr_st<=100; // IDLE 
		 100,101,102,103,104,105,106,107,108,109,
		 110,111,112,113,114,115,116,117,118:      wr_st<=wr_st+1 ; 
		 119:wr_st <= 200;
		 200:if ( cr_cntr == ip_pack_lenr )wr_st<=300; 
		 default wr_st<=0;
		 endcase 
		  
		 reg [11:0] rd_addr ;
		 always @ (posedge clk) if (rst) wr_st<=0; else case (wr_st) 
		 100:begin m_ip_tx_valid <=1;m_ip_tx_data<= {ip_version, header_len} ;end 
		 101:begin m_ip_tx_valid <=1;m_ip_tx_data<= 0 ;end 		 
		 102:begin m_ip_tx_valid <=1;m_ip_tx_data<=  s_ip_pack_len[15:8] ;end 
		 103:begin m_ip_tx_valid <=1;m_ip_tx_data<= s_ip_pack_len[7:0] ;end 
		 104:begin m_ip_tx_valid <=1;m_ip_tx_data<= s_ip_id[15:8] ;end 
		 105:begin m_ip_tx_valid <=1;m_ip_tx_data<=  s_ip_id[7:0] ;end 
		 106:begin m_ip_tx_valid <=1;m_ip_tx_data<=  'h40 ;end 
		 107:begin m_ip_tx_valid <=1;m_ip_tx_data<= 0 ;end 
		 108:begin m_ip_tx_valid <=1;m_ip_tx_data<=  s_ip_TTL ;end 
		 109:begin m_ip_tx_valid <=1;m_ip_tx_data<=  s_ip_type; end 
		 110:begin m_ip_tx_valid <=1;m_ip_tx_data<= checksum[15:8] ;end 
		 111:begin m_ip_tx_valid <=1;m_ip_tx_data<= checksum[7:0]  ;end 
		 112:begin m_ip_tx_valid <=1;m_ip_tx_data<= s_ip_src[31:24];end 
		 113:begin m_ip_tx_valid <=1;m_ip_tx_data<= s_ip_src[23:16] ;end 
		 114:begin m_ip_tx_valid <=1;m_ip_tx_data<= s_ip_src[15:8] ;end 
		 115:begin m_ip_tx_valid <=1;m_ip_tx_data<=  s_ip_src[7:0] ;end 
		 116:begin m_ip_tx_valid <=1;m_ip_tx_data<= s_ip_dst[31:24] ;end 
		 117:begin m_ip_tx_valid <=1;m_ip_tx_data<= s_ip_dst[23:16] ;end 
		 118:begin m_ip_tx_valid <=1;m_ip_tx_data<=  s_ip_dst[15:8] ;end 
		 119:begin m_ip_tx_valid <=1;m_ip_tx_data<= s_ip_dst[7:0] ;end 
		 200:begin m_ip_tx_valid <=1;m_ip_tx_data<= s_ip_data[7:0] ;end 
		 default 		 begin m_ip_tx_valid <=0;m_ip_tx_data<=  0 ;end  
		 endcase 
		 
	     always @ (posedge clk) s_ip_data_ack <= ( wr_st == 200 &&  cr_cntr != ip_pack_lenr ) || ( wr_st == 119 ) ; 
  		 
		 endmodule
		 
		 
		 
module ip_chksum_gen(
		 input clk,rst,
		 input valid,
		 output ready ,
		 input [15:0] in0,in1,in2,in3,in4,
		 input [15:0] in5,in6,in7,in8,in9,
		 output reg [15:0] checksum
		 ); 
		 
//checksum function
function    [31:0]  checksum_adder
  (
    input       [31:0]  dataina,
    input       [31:0]  datainb
  );
  
  begin
    checksum_adder = dataina + datainb;
  end
endfunction

function    [31:0]  checksum_out
  (
    input       [31:0]  dataina
  );
  
  begin
    checksum_out = dataina[15:0]+dataina[31:16];
  end
  
endfunction

//checksum generation

reg  [16:0] checksum_tmp0 ;
reg  [16:0] checksum_tmp1 ;
reg  [16:0] checksum_tmp2 ;
reg  [16:0] checksum_tmp3 ;
reg  [16:0] checksum_tmp4 ;
reg  [17:0] checksum_tmp5 ;
reg  [17:0] checksum_tmp6 ;
reg  [18:0] checksum_tmp7 ;
reg  [19:0] checksum_tmp8 ;
reg  [19:0] check_out ;
reg  [19:0] checkout_buf ; 

reg [4:0]valid_r ;always @ (posedge clk)  valid_r <={valid_r[3:0],valid} ;
assign ready = valid_r[4];


always@(posedge clk)begin 
        checksum_tmp0 <= checksum_adder(in0,in1);
        checksum_tmp1 <= checksum_adder(in2,in3) ;
        checksum_tmp2 <= checksum_adder(in4,in5) ;
        checksum_tmp3 <= checksum_adder(in5,in7) ;
        checksum_tmp4 <= checksum_adder(in8,in9) ;// stage 1 
        checksum_tmp5 <= checksum_adder(checksum_tmp0, checksum_tmp1) ;
        checksum_tmp6 <= checksum_adder(checksum_tmp2, checksum_tmp3) ;
        checksum_tmp7 <= checksum_adder(checksum_tmp5, checksum_tmp6) ;
        checksum_tmp8 <= checksum_adder(checksum_tmp4, checksum_tmp7) ; // stage2
        check_out     <= checksum_out(checksum_tmp8) ; //stage3 
        checkout_buf  <= checksum_out(check_out) ; // stage4
		checksum <= ~ checkout_buf[15:0] ; // stage5 
end


endmodule 
		 
		 

上述代码时序仿真通过,数据的真确定简单确认了,CHECKSUM等细节还要在整体统一调试时候进行验证分析。

?

?

下一步要

1,写好并验证mac+物理层组包,也是分两个两个模块mac.v和phy.v,分别写好之后串联在一起。

2,写一个选择模块,在mac输入之前,选择是ip层来的信号输入还是arp_reply以及icmp_reply回复。

3,有了上述发送部分,可以尝试在arp_cache.v里以及电脑里面加入对方ip和mac对应,尝试在FPGA上用UDP协议发给电脑数据包,并使用wireshark观察是否对,如果不成功进行调试。

4,成功后就要开始写接受的实现。就再分析。

下午要出去一趟,估计晚上才能回来,回来继续写。正确今天写好并仿真好mac和phy。明天抽时间进行实际包调试。

  网络协议 最新文章
使用Easyswoole 搭建简单的Websoket服务
常见的数据通信方式有哪些?
Openssl 1024bit RSA算法---公私钥获取和处
HTTPS协议的密钥交换流程
《小白WEB安全入门》03. 漏洞篇
HttpRunner4.x 安装与使用
2021-07-04
手写RPC学习笔记
K8S高可用版本部署
mySQL计算IP地址范围
上一篇文章      下一篇文章      查看所有文章
加:2021-12-05 12:21:50  更:2021-12-05 12:22:29 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 9:39:50-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码