10G光口UDP协议实现之UDP_IP打包实现代码

66 篇文章 23 订阅
58 篇文章 27 订阅

这里主要是加上了UDP和IP和HEADER。

为了简化设计提高运行效率,这里UDP没有实现CHECK SUM。

代码编译通过,接下来要进行仿真,死磕时序,可能今晚有时间搞搞。



module pack_udp_ip_tb ;

reg  clk = 0 , rst  = 1  ;
always #5 clk = ~clk ;  
initial begin 
$dumpfile("v.vcd");
$dumpvars(0);
#100000;
$finish ;

end 

wire [31:0]  s_src_ip = {8'd192,8'd168,8'd3,8'd12} ;
wire [31:0]  s_dst_ip = {8'd192,8'd168,8'd3,8'd12} ;
wire [31:0]  s_src_port = 'h4321 ;
wire [31:0]  s_dst_port = 'h1234 ; 
 
reg s_valid = 0 ;
wire s_ready ;
reg [64:0]  s_din  = 0 ;


always@(posedge clk ) if (rst)s_din<= {8'h00,8'h0,8'h0,8'h0,8'h0,8'h0,8'h0,8'h00}  ;else  
s_din <= s_din + {8'h01,8'h01,8'h01,8'h01,8'h01,8'h01,8'h01,8'h01} ;

reg [3:0]  s_byte_cnt = 8 ;
reg [15:0] s_byte_len = 256 ;

wire [63:0] m_dout;
wire [7:0 ]m_keep ;
wire m_valid,m_last ;

 pack_udp_ip  pack_udp_ip ( 
		 .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_valid  ( s_valid )          ,
		 .s_ready ( s_ready )          ,
		 .s_din ( s_din )      ,
		 .s_byte_cnt ( s_byte_cnt ) ,
		 .s_byte_len ( s_byte_len ) ,
		 
		 .m_ready ( 1'b1  ) , // mac
		 .m_dout ( m_dout )  ,
		 .m_keep ( m_keep )  ,
		 .m_valid ( m_valid ),
		 .m_last (m_last  ) 
);

endmodule 


module pack_udp_ip ( 
		 input clk,rst,
		 input [31:0] s_src_ip,s_dst_ip,
		 input [15:0] s_src_port,s_dst_port,
		 
		 input s_valid           ,
		 output s_ready          ,
		 input [63:0] s_din      ,
		 input [3:0] s_byte_cnt ,
		 input [15:0] s_byte_len ,
		 
		 input        m_ready , // mac
		 output reg [63:0] m_dout  ,
		 output reg [7:0] m_keep  ,
		 output reg  m_valid,m_last 
);

		  wire [3:0] ip_version     = 4'h4     ;  //ipv4
		  wire [3:0] header_len     = 4'h5     ;  //header length

wire [15:0] checksum ;
reg  [15:0] s_ip_pack_len_p28_r ; always@(posedge clk)  s_ip_pack_len_p28_r <= 28 + s_byte_len ;
reg  [15:0] s_ip_pack_len_p8_r ; always@(posedge clk)  s_ip_pack_len_p8_r <= 8 + s_byte_len ;
wire [15:0] s_ip_id = 16'hAABB ;
wire [7:0 ] s_ip_TTL = 64 ;
wire [7:0 ] s_ip_type = 111;//UDP TYPE
wire [63:0] bit_ch_u64 ;
reg st_en_bit_ch = 0 ; 
wire [7:0] bit_ch_m_keep ;
wire [63:0]bit_ch_m_q64 ;
 bit_ch#( .FIRST_LEN(4) ,  .AW(6)   ) ii(
  .clk( clk ) ,
  .rst( rst ) , 
  .s_valid( s_valid       ) ,
  .s_d64( s_d64 ) ,
  .s_ready (s_ready) , // s_ready = s_valid if fifo not full 
  .s_cntr (s_byte_cnt ) ,

  .m_q64( bit_ch_m_q64 ) ,
  .m_valid(bit_ch_m_valid ) , 
  .m_last(bit_ch_m_last ) ,
  .m_keep ( bit_ch_m_keep ) ,
  .m_ready( st_en_bit_ch  ) 
); 

always @ (posedge clk)if (rst)st_en_bit_ch<=0;
else  case (st)
22,23:   st_en_bit_ch<=1;
default  st_en_bit_ch<=0;
endcase 
 

 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_p20_r) , //1
		   .in2(s_ip_id ) ,//2
		   .in3( 16'h0000 ) ,  //3
		   .in4( {s_ip_TTL,s_ip_type} ) , //4
		   .in5( 16'h0 ) ,//5
		   .in6(s_src_ip[31:16] ) ,//6
		   .in7(s_src_ip[15:0] ) ,//7
		   .in8(s_dst_ip[31:16]  ) ,//8
		   .in9(s_dst_ip[15:0]  ) ,//9 
		   .checksum(checksum)
		 ); 
		 
		 reg [7:0] st; always @ (posedge clk)if (rst) st<=0; else case(st)
		 0  : st<=10;
		 10 : if (s_valid & m_ready )st<=15;
		 15:st<=16;16:st<=17;17:st<=20;
		 20,21,22,23:st<=st+1;
		 24 : if (bit_ch_m_last)   st<=10;
		 default st<=10;
		 endcase 
		 
		 /*
		 0
		 m_dout[ 0*8 +: 8 ] <= {ip_version[3:0], header_len[3:0]}  ;
		 m_dout[ 1*8 +: 8 ] <= 0  ;
		 m_dout[ 2*8 +: 8 ] <=  s_ip_pack_len_p28_r[15:8] ;
		 m_dout[ 3*8 +: 8 ] <=  s_ip_pack_len_p28_r[7:0]  ;
		 
		 
		 
		 100:begin  m_ip_tx_data<= {ip_version[3:0], header_len[3:0]} ;end 
		 101:begin  m_ip_tx_data<= 0 ;end 		 
		 102:begin  m_ip_tx_data<=  s_ip_pack_len_p20_r[15:8] ;end //OK
		 103:begin  m_ip_tx_data<=  s_ip_pack_len_p20_r[7:0] ;end  //OK
		 ///
		 
		 1		 
		 m_dout[ 0*8 +: 8 ] <= s_ip_id[15:8]  ;
		 m_dout[ 1*8 +: 8 ] <= s_ip_id[7:0]  ;
		 m_dout[ 2*8 +: 8 ] <=  0 ;
		 m_dout[ 3*8 +: 8 ] <=  0 ;
		 
		 
		 
		 104:begin  m_ip_tx_data<= s_ip_id[15:8] ;end //ok
		 105:begin  m_ip_tx_data<=  s_ip_id[7:0] ;end //ok
		 106:begin  m_ip_tx_data<=  0 ; end 
		 107:begin  m_ip_tx_data<=  0 ; end 
		 /
		 
		 2
		 m_dout[ 0*8 +: 8 ] <= s_ip_TTL  ;
		 m_dout[ 1*8 +: 8 ] <= s_ip_type ;
		 m_dout[ 2*8 +: 8 ] <=  checksum[15:8] ;;
		 m_dout[ 3*8 +: 8 ] <=  checksum[7:0] ; ;
		 
		 
		 108:begin  m_ip_tx_data<=  s_ip_TTL ;end  //ok 
		 109:begin  m_ip_tx_data<=  s_ip_type; end //ok 
		 110:begin  m_ip_tx_data<= checksum[15:8] ;end 
		 111:begin  m_ip_tx_data<= checksum[7:0]  ;end 
		 
		 //
		 3
		 m_dout[ 0*8 +: 8 ] <=  s_ip_src[3*8+:8] ;
		 m_dout[ 1*8 +: 8 ] <=  s_ip_src[2*8+:8] ;
		 m_dout[ 2*8 +: 8 ] <=  s_ip_src[1*8+:8] ;
		 m_dout[ 3*8 +: 8 ] <=  s_ip_src[0*8+:8]  ;
		 
		 
		 112:begin  m_ip_tx_data<= s_ip_src[31:24];end 
		 113:begin  m_ip_tx_data<= s_ip_src[23:16] ;end 
		 114:begin  m_ip_tx_data<= s_ip_src[15:8] ;end 
		 115:begin  m_ip_tx_data<=  s_ip_src[7:0] ;end 
		 
		 
		 
		 4	 
		 m_dout[ 0*8 +: 8 ] <=  s_ip_dst[3*8+:8] ;
		 m_dout[ 1*8 +: 8 ] <=  s_ip_dst[2*8+:8] ;
		 m_dout[ 2*8 +: 8 ] <=  s_ip_dst[1*8+:8] ;
		 m_dout[ 3*8 +: 8 ] <=  s_ip_dst[0*8+:8] ;
		 
		 
		 116:begin  m_ip_tx_data<= s_ip_dst[31:24] ;end 
		 117:begin  m_ip_tx_data<= s_ip_dst[23:16] ;end 
		 118:begin  m_ip_tx_data<=  s_ip_dst[15:8] ;end 
		 119:begin  m_ip_tx_data<= s_ip_dst[7:0] ;end 
		 
		 */
		 
		 always @ (posedge clk) if (rst){ m_valid,m_last  }<=0 ; else  case (st)
		 20: begin   ip_hdr_word_0 ;end  
		 21: begin   ip_hdr_word_1 ;end  
		 22: begin   ip_hdr_word_2 ;end  
		 23: begin   ip_hdr_word_3 ;end  
		 24: begin   bit_ch_bypass ;end   
		 default { m_valid,m_last  }<=0 ;
		 endcase  
		 		 
		 
		 task ip_hdr_word_0		; begin 		 
		 // 0
		 m_dout[ 0*8 +: 8 ] <= {ip_version[3:0], header_len[3:0]}  ;
		 m_dout[ 1*8 +: 8 ] <= 0  ;
		 m_dout[ 2*8 +: 8 ] <=  s_ip_pack_len_p28_r[15:8] ;
		 m_dout[ 3*8 +: 8 ] <=  s_ip_pack_len_p28_r[7:0]  ;
		 m_dout[ 4*8 +: 8 ] <= s_ip_id[15:8]  ;
		 m_dout[ 5*8 +: 8 ] <= s_ip_id[7:0]  ;
		 m_dout[ 6*8 +: 8 ] <=  0 ;
		 m_dout[ 7*8 +: 8 ] <=  0 ;
		 m_keep <=8 ;  m_valid <= 1;  m_last <= 0; 
		 end 		 endtask 
 

		 task ip_hdr_word_1		; begin 		 
		 //	 2
		 m_dout[ 0*8 +: 8 ] <= s_ip_TTL  ;
		 m_dout[ 1*8 +: 8 ] <= s_ip_type ;
		 m_dout[ 2*8 +: 8 ] <=  checksum[15:8] ;
		 m_dout[ 3*8 +: 8 ] <=  checksum[7:0] ;
         // 3
		 m_dout[ 4*8 +: 8 ] <=  s_src_ip[3*8 +: 8] ;
		 m_dout[ 5*8 +: 8 ] <=  s_src_ip[2*8 +: 8] ;
		 m_dout[ 6*8 +: 8 ] <=  s_src_ip[1*8 +: 8] ;
		 m_dout[ 7*8 +: 8 ] <=  s_src_ip[0*8 +: 8]  ;

		 m_keep <=8 ;  m_valid <= 1;  m_last <= 0;  
		 end 		 endtask 

		 task ip_hdr_word_2		; begin 	
		 m_keep <=8 ;  m_valid <= 1;  m_last <= 0; 		 
		 m_dout[ 0*8 +: 8 ] <=   s_dst_ip[3*8 +: 8] ;
		 m_dout[ 1*8 +: 8 ] <=   s_dst_ip[2*8 +: 8] ;
		 m_dout[ 2*8 +: 8 ] <=   s_dst_ip[1*8 +: 8] ;
		 m_dout[ 3*8 +: 8 ] <=   s_dst_ip[0*8 +: 8] ;
		 m_dout[ 4*8 +: 8 ] <=   s_src_port[1*8 +: 8 ] ;
		 m_dout[ 5*8 +: 8 ] <=   s_src_port[0*8 +: 8 ]  ;
		 m_dout[ 6*8 +: 8 ] <=   s_dst_port[1*8 +: 8 ]  ;
		 m_dout[ 7*8 +: 8 ] <=   s_dst_port[0*8 +: 8 ]  ;

/*

		300:begin  wr_en<=1;wr_data<= src_port_reg[15:8]; wr_addr<=0 ; end
			301:begin  wr_en<=1;wr_data<= src_port_reg[7:0] ; wr_addr<=1; end
			302:begin  wr_en<=1;wr_data<= dst_port_reg[15:8]; wr_addr<=2 ; end
			303:begin  wr_en<=1;wr_data<= dst_port_reg[7:0] ; wr_addr<=3; end
			
	*/		

		 
		 end 		 endtask 

		 task ip_hdr_word_3		; begin 		 
		// 		 	4	 
		
		 m_keep <=8 ;  m_valid <= 1;  m_last <= 0; 		 
		 m_dout[ 0*8 +: 8 ] <=   s_ip_pack_len_p8_r[15:8] ;
		 m_dout[ 1*8 +: 8 ] <=   s_ip_pack_len_p8_r[7:0 ] ;
		 m_dout[ 2*8 +: 8 ] <=   0 ;
		 m_dout[ 3*8 +: 8 ] <=   0 ;
		 
		 m_dout[ 4*8 +: 8 ] <=   bit_ch_m_q64[0*8 +: 8 ] ;
		 m_dout[ 5*8 +: 8 ] <=   bit_ch_m_q64[1*8 +: 8 ]  ;
		 m_dout[ 6*8 +: 8 ] <=   bit_ch_m_q64[2*8 +: 8 ]  ;
		 m_dout[ 7*8 +: 8 ] <=   bit_ch_m_q64[3*8 +: 8 ]  ;

		/*
			304:begin  wr_en<=1;wr_data<= s_ip_pack_len_p8_r[15:8]; wr_addr<=4 ; end
			305:begin  wr_en<=1;wr_data<= s_ip_pack_len_p8_r[7:0]; wr_addr<=5 ; end
			306:begin  wr_en<=0;wr_data<= 0; wr_addr<=0 ; end
			307:begin  wr_en<=0;wr_data<= 0; wr_addr<=0 ; end
		*/
		
		
		 m_keep <=8 ;  m_valid <= 1;  m_last <= 0; 
		 end 		 endtask 



		 task  bit_ch_bypass  ; begin 		
		 m_dout[ 0*8 +: 64 ]  <=   bit_ch_m_q64[0*8 +: 64 ]  ; 
		 m_keep <=bit_ch_m_keep ;  m_valid <=bit_ch_m_valid ;  m_last <= bit_ch_m_last; 
		 end 		 endtask 
		 
		 		 
		 


endmodule 



module ip_chksum_gen(
		 input clk,rst,
		 input valid,
		 output reg 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  [16:0] check_out ;
reg  [15:0] checkout_buf ; 

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


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(in6,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 


/*


 bit_ch#( .FIRST_LEN(4) ,  .AW(6)   ) ii(
  .clk( clk ) ,
  .rst( rst ) , 
  .s_valid( ) ,s_ready(),
  .s_d64( ) ,
  .s_cntr ( ) ,

  .m_q64( ) ,
  .m_valid( ) , 
  .m_last( ) ,
  .m_keep ( ) ,
  .m_ready( ) 
);


*/

module  bit_ch#(
		parameter FIRST_LEN =2,
        parameter AW = 4   
)(
input clk,rst, s_valid,
input [63:0] s_d64,
input [4:0] s_cntr ,
output reg s_ready ,

output [63:0] m_q64,
output reg m_valid, m_last,
output reg [7:0] m_keep ,
input m_ready
);


wire [AW:0] gap ;
wire empty_w ;	
wire empty = ( m_ready == 0 ) ? 1: empty_w;
	

reg [3:0] rd_byte_cntr ;

always @ (posedge clk)
case (rd_byte_cntr)
0:m_keep<=8'h00000000;
1:m_keep<=8'b00000001;
2:m_keep<=8'b00000011;
3:m_keep<=8'b00000111;
4:m_keep<=8'b00001111;
5:m_keep<=8'b00011111;
6:m_keep<=8'b00111111;
7:m_keep<=8'b01111111;
8:m_keep<=8'b11111111;
endcase 

wire full; 
reg empty_r ;always @ (posedge clk )empty_r <= empty ;
always @ (*) if ( {empty_r,empty} == 2'b10 ) rd_byte_cntr = FIRST_LEN;else  rd_byte_cntr = (gap[3]) ?  8  :  gap  ; 
wire rd_en = ~empty ; 
always@(posedge clk) m_valid <= rd_en ;

always@(*)  m_last = { m_valid,rd_en }== 2'b10 ; 


always @ (*)s_ready = gap[3] ; // gap>=8

bit_fifo#(.AW(AW)) bit_fifo(
          .clk(clk ),
		  .rst(rst ),
		  .wr_din( s_d64),
          .wr_byte_cntr(  s_cntr  ),
		  .wr_en(s_valid ) ,
		  .rd_dout( m_q64) ,
          .rd_byte_cntr(rd_byte_cntr ) ,
		  .rd_en(rd_en ) , 
		  .empty(empty_w ),
		  .full(  ),
		  .gap(gap )
    ); 

endmodule 
	

 
	

module bit_fifo#(
        parameter AW = 4   
    )(
        input clk,rst,
		input [ 64-1:0]wr_din,
        input [3:0] wr_byte_cntr,
		input wr_en ,
		output reg   [ 64-1 : 0 ]rd_dout ,
        input   [ 3 : 0 ] rd_byte_cntr ,
		input  rd_en , 
		output empty,full,
		output reg [AW:0]gap
    ); 
 
    parameter MAX_FIFO_LEN = ( 1 << AW ) ;
    reg [ 8-1:0] buff[0:  MAX_FIFO_LEN -1] ;
    integer i ;          initial    for(i=0;i<MAX_FIFO_LEN;i=1+i)  buff[i] = 0;       
    assign full  = gap == MAX_FIFO_LEN ;
	assign empty = gap == 0 ; 
	reg [ AW-1:0] wr_ptr =0 , rd_ptr = 0  ;
    always@(posedge clk) if (rst)   wr_ptr <= 0 ; else if ( wr_en  ) wr_ptr <= wr_ptr + wr_byte_cntr ;
    always@(posedge clk) if (rst)   rd_ptr <= 0 ; else if ( rd_en  ) rd_ptr <= rd_ptr + rd_byte_cntr ; 
 
	
	wire  [ AW-1:0] wr_ptr_plus_0 = wr_ptr + 0 ;
	wire  [ AW-1:0] wr_ptr_plus_1 = wr_ptr + 1 ;
	wire  [ AW-1:0] wr_ptr_plus_2 = wr_ptr + 2 ;
	wire  [ AW-1:0] wr_ptr_plus_3 = wr_ptr + 3 ;
	wire  [ AW-1:0] wr_ptr_plus_4 = wr_ptr + 4 ;
	wire  [ AW-1:0] wr_ptr_plus_5 = wr_ptr + 5 ;
	wire  [ AW-1:0] wr_ptr_plus_6 = wr_ptr + 6 ;
	wire  [ AW-1:0] wr_ptr_plus_7 = wr_ptr + 7 ; 
	
	wire  [ AW-1:0] rd_ptr_plus_0 = rd_ptr + 0 ;
	wire  [ AW-1:0] rd_ptr_plus_1 = rd_ptr + 1 ;
	wire  [ AW-1:0] rd_ptr_plus_2 = rd_ptr + 2 ;
	wire  [ AW-1:0] rd_ptr_plus_3 = rd_ptr + 3 ;
	wire  [ AW-1:0] rd_ptr_plus_4 = rd_ptr + 4 ;
	wire  [ AW-1:0] rd_ptr_plus_5 = rd_ptr + 5 ;
	wire  [ AW-1:0] rd_ptr_plus_6 = rd_ptr + 6 ;
	wire  [ AW-1:0] rd_ptr_plus_7 = rd_ptr + 7 ;  
	
 always@(posedge clk) if (wr_en )   buff[ wr_ptr_plus_0 ]<= wr_din[ 0*8 +: 8] ;
 always@(posedge clk) if (wr_en )   buff[ wr_ptr_plus_1 ]<= wr_din[ 1*8 +: 8] ;
 always@(posedge clk) if (wr_en )   buff[ wr_ptr_plus_2 ]<= wr_din[ 2*8 +: 8] ;
 always@(posedge clk) if (wr_en )   buff[ wr_ptr_plus_3 ]<= wr_din[ 3*8 +: 8] ;
 always@(posedge clk) if (wr_en )   buff[ wr_ptr_plus_4 ]<= wr_din[ 4*8 +: 8] ;
 always@(posedge clk) if (wr_en )   buff[ wr_ptr_plus_5 ]<= wr_din[ 5*8 +: 8] ;
 always@(posedge clk) if (wr_en )   buff[ wr_ptr_plus_6 ]<= wr_din[ 6*8 +: 8] ;
 always@(posedge clk) if (wr_en )   buff[ wr_ptr_plus_7 ]<= wr_din[ 7*8 +: 8] ;
 
 always@(posedge clk) if (rd_en )   rd_dout[ 0*8 +: 8] <=buff[rd_ptr_plus_0 ];
 always@(posedge clk) if (rd_en )   rd_dout[ 1*8 +: 8] <=buff[rd_ptr_plus_1 ];
 always@(posedge clk) if (rd_en )   rd_dout[ 2*8 +: 8] <=buff[rd_ptr_plus_2 ];
 always@(posedge clk) if (rd_en )   rd_dout[ 3*8 +: 8] <=buff[rd_ptr_plus_3 ];
 always@(posedge clk) if (rd_en )   rd_dout[ 4*8 +: 8] <=buff[rd_ptr_plus_4 ];
 always@(posedge clk) if (rd_en )   rd_dout[ 5*8 +: 8] <=buff[rd_ptr_plus_5 ];
 always@(posedge clk) if (rd_en )   rd_dout[ 6*8 +: 8] <=buff[rd_ptr_plus_6 ];
 always@(posedge clk) if (rd_en )   rd_dout[ 7*8 +: 8] <=buff[rd_ptr_plus_7 ];   


	always@(posedge clk)
    casex ({rst,wr_en,rd_en})
        3'b1xx : gap <= 0;
        3'b010 : gap <= gap + wr_byte_cntr;
        3'b001 : gap <= gap - rd_byte_cntr;
		3'b011 : gap <= gap + wr_byte_cntr - rd_byte_cntr;
    endcase
	
endmodule


这里面主要注意BIT_CH模块加入的时序的打磨。这个仿真成功后立即做ICMP_REPLAY的组包并进行仿真。

这样之后发送部分就写完毕了,接下来开始写接受部分的解析和分支处理。在一个接收模块里面解析出ARP ICMP和UDP,并提取相关参数,分给另外一些对应模块里面处理。其中ARP和ICMP发给主状态机,UDP报文则发给用户程序。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值