⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 udp.v

📁 具备GMII接口和ARP协议功能的千兆以太网控制器。经过Xilinx SPATAN-III FPGA验证, Verilog描述
💻 V
字号:
module udp(
	   clk,
	   rst,
	   data_i,
	   addr,
	   info_en,
	   length,
	   headadd,
	   des_ip,
	   sou_ip,
	   des_port,
	   sou_port,
	   send_udp,
	   udp_over,
	   udp_ing,
	   udata_o
	   );
    input clk;
    input rst;
    input [7:0] data_i;
    output [10:0] addr;	    //modified, orignal is [11:0]
    reg[10:0] addr;
    output info_en;
    reg info_en;
    input[9:0] length;
    input headadd;	   //modified, orignal is *input headadd*
    input[31:0] des_ip;
    input[31:0] sou_ip;
    input[15:0] des_port;
    input[15:0] sou_port;
    input send_udp;
    output udp_over;
    reg udp_over;
    output udp_ing;
    reg udp_ing;
    output [7:0] udata_o;
    reg[7:0] udata_o;
    
    
    reg[10:0] counter;
    
    reg[2:0] current;
    reg[2:0] next;
    
    wire[15:0] length_i;
    wire[15:0] length_u;
    reg[15:0] p_counter;

    reg[31:0] ip_checksum;
    reg msb;
    reg[31:0] time_stamp;
   
    
    parameter IDLE=3'b001, RD=3'b010, SEND=3'b100;

assign length_i={6'h00,length+28};// length_i={6'h00,length+40};
assign length_u={6'h00,length+8};// length_u={6'h00,length+20}
/******8B UDP head, 20B IP head, 2B protocol type**********/   
always@(current or send_udp or udp_over)
begin
	next=3'bxxx;
	case(current)
	IDLE: begin
		if(send_udp)
		next=RD;
		else
		next=IDLE;
	end
	RD: next=SEND;
	SEND: begin
		if(udp_over)	  //if(counter==length+42)
		next=IDLE;
		else
		next=SEND;
	end
	default: next=IDLE;
	endcase
end
always@(posedge clk or negedge rst)
begin
	if(!rst) current<=IDLE;
	else current<=next;
end

/****************get the fifo****************/
always@(posedge clk or negedge rst)
begin
	if(!rst) begin
		info_en<=1'b0;
	end
	else begin
		if(next==RD)
		info_en<=1'b1;
		else
		info_en<=1'b0;
	end
end
/*****************the byte counter*************/
always@(posedge clk or negedge rst)
begin
	if(!rst) begin
		counter<=11'h000;
	end
	else begin
		if(next==SEND)
		counter<=counter+1;
		else
		counter<=11'h000;
	end
end
/*****************the packet counter***********/
always@(posedge clk or negedge rst)
begin
	if(!rst) p_counter<=16'h0000;
	else begin
		if(send_udp)
		p_counter<=p_counter+1;
	end
end
/****************the addr ********************/
always@(posedge clk or negedge rst)
begin
	if(!rst) addr<=11'h000;
	else begin
		if(next==SEND)
		begin
			if(counter==28) //if(counter==40)
			addr<={headadd,10'h000};
			else 
			addr<=addr+1;
		end
		else 
		addr<=11'h000;
	end
end
always@(posedge clk or negedge rst)
begin
	if(!rst) begin
		udata_o<=8'h00;
		udp_ing<=1'b0;
	end
	else begin
		if(next==SEND)
		case(counter)
		/******the protocol type 0800******/
		0: begin			//modifed, orignal there is no 0800 head
			udata_o<=8'h08;
			udp_ing<=1'b1;
		end
		1: udata_o<=8'h00;
		/*******the IP head*****/
		2: udata_o<=8'h45;
		3: udata_o<=8'h00;
		4: udata_o<=length_i[15:8];
		5: udata_o<=length_i[7:0];
		6: udata_o<=p_counter[15:8];
		7: udata_o<=p_counter[7:0];
		8: udata_o<=8'h00;
		9: udata_o<=8'h00;
		10: udata_o<=8'h20;
		11:udata_o<=8'h11;
		12:udata_o<=ip_checksum[15:8];
		13:udata_o<=ip_checksum[7:0];//the IP head check sum
		14:udata_o<=sou_ip[31:24];
		15:udata_o<=sou_ip[23:16];
		16:udata_o<=sou_ip[15:8];
		17:udata_o<=sou_ip[7:0];
		18:udata_o<=des_ip[31:24];
		19:udata_o<=des_ip[23:16];
		20:udata_o<=des_ip[15:8];
		21:udata_o<=des_ip[7:0];
		/*******the UDP head*******/
		22:udata_o<=sou_port[15:8];
		23:udata_o<=sou_port[7:0]; //source port
		24:udata_o<=des_port[15:8];
		25:udata_o<=des_port[7:0]; // destination port
		26:udata_o<=length_u[15:8];
		27:udata_o<=length_u[7:0];
		28:udata_o<=8'h00;
		29:udata_o<=8'h00;//udp data checksum   (invalid)
		/*******the RTP head*******/
		/*
		30:udata_o<=8'h80;
		31:udata_o<=8'h21;
		32:udata_o<=p_counter[15:8];
		33:udata_o<=p_counter[7:0];
		34:udata_o<=time_stamp[31:24];
		35:udata_o<=time_stamp[23:16];
		36:udata_o<=time_stamp[15:8];
		37:udata_o<=time_stamp[7:0];
		38:udata_o<=8'h11;
		39:udata_o<=8'h66;
		40:udata_o<=8'h88;
		41:udata_o<=8'h99;//the SSRC
		*/
		default:udata_o<=data_i;
		endcase
		else begin
			udata_o<=8'h00;
			udp_ing<=1'b0;
		end
	end
end
always@(posedge clk or negedge rst)
begin
	if(!rst) udp_over<=1'b0;
	else begin
		if(counter==length+29) //if(counter==length+41)
		udp_over<=1'b1;
		else
		udp_over<=1'b0;
	end
end	
/**********compute the IP head checksum*******/
always@(posedge clk or negedge rst)
begin
	if(!rst) begin
		ip_checksum<=32'h00029aec;
		msb<=1'b0;
	end
	else begin
		if(next==SEND)	begin
			case(counter)
			0: ip_checksum<=ip_checksum+{16'h0000,sou_ip[31:16]^16'hffff};//^16'hffff;
			1: ip_checksum<=ip_checksum+{16'h0000,sou_ip[15:0]^16'hffff};//^16'hffff;
			2: ip_checksum<=ip_checksum+{16'h0000,length_i^16'hffff};//^16'hffff;
			3: ip_checksum<=ip_checksum+{16'h0000,p_counter^16'hffff};//^16'hffff;
			4: ip_checksum<=ip_checksum+{16'h0000,des_ip[31:16]^16'hffff};//^16'hffff;
			5: ip_checksum<=ip_checksum+{16'h0000,des_ip[15:0]^16'hffff};//^16'hffff;
			6: {msb,ip_checksum[15:0]}<={1'b0,ip_checksum[15:0]}+{1'b0,ip_checksum[31:16]};
			7: ip_checksum[15:0]<=ip_checksum[15:0]+{15'h0000,msb};
			endcase
		end
		else begin
			msb<=1'b0;
			ip_checksum<=32'h00029aec;
		end
	end
end
/***********************the time_stamp******************/			  		
always@(posedge clk or negedge rst)
begin
	if(!rst) time_stamp<=32'h0000_0000;
	else begin
		time_stamp<=time_stamp+1;
	end
end

endmodule

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -