📄 udp.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 + -