?? ip_recv.v
字號(hào):
`define IP_ADDRR 32'hc0a80102
`define VERS 31:28
`define HLEN 27:24
`define TLEN 15:0
module IP_recv(
input clk,
input reset,
input ivalid,
input [31:0] ip_data,
output reg udp_valid,
output reg [31:0] udp_data
);
reg [15:0] cnt;
reg [16:0] tmp_accum1, tmp_accum2, tmp_accum3;
reg [15:0] accum1, accum2, final_accum,checksum, head_length, full_length, data_length;
reg [31:0] ip_data_buffer;
reg options, bufcnt, start_data;
reg [7:0] proto;
always @(posedge clk) begin
if (reset) begin
cnt <= 16'b0;
bufcnt <= 1'b1;
udp_data <= 32'h0;
udp_valid <= 1'b0;
ip_data_buffer <= 32'h0;
options <= 1'b0;
data_length <= 16'h0;
start_data <= 1'b0;
proto <= 8'h0;
end
else if (ivalid) begin
case (cnt)
0: begin
udp_valid <= 1'b0;
accum1 <= ip_data[15:0];
accum2 <= ip_data[31:16];
head_length <= ip_data[`HLEN] << 2;
full_length <= ip_data[`TLEN];
if (ip_data[`HLEN] == 4'd5) begin
options <= 1'b0;
end
else if (ip_data[`HLEN] > 4'd5) begin
options <= 1'b1;
end
cnt <= cnt + 16'b1;
bufcnt <= 1'b1;
end
1: begin
tmp_accum1 = (accum1 + ip_data[15:0]);
accum1 <= tmp_accum1[15:0] + tmp_accum1[16];
tmp_accum2 = (accum2 + ip_data[31:16]);
accum2 <= tmp_accum2[15:0] + tmp_accum2[16];
data_length <= full_length - head_length;
cnt <= cnt + 16'b1;
start_data <= 1'b1;
end
2: begin
tmp_accum2 = (accum2 + ip_data[31:16]);
accum2 <= tmp_accum2[15:0] + tmp_accum2[16];
accum1 <= accum1;
checksum <= ip_data[15:0];
proto <= ip_data[23:16];
data_length <= data_length >> 2;
cnt <= cnt + 16'b1;
end
3: begin
tmp_accum1 = (accum1 + ip_data[15:0]);
accum1 <= tmp_accum1[15:0] + tmp_accum1[16];
tmp_accum2 = (accum2 + ip_data[31:16]);
accum2 <= tmp_accum2[15:0] + tmp_accum2[16];
cnt <= cnt + 16'b1;
end
4: begin
tmp_accum1 = (accum1 + ip_data[15:0]);
accum1 <= tmp_accum1[15:0] + tmp_accum1[16];
tmp_accum2 = (accum2 + ip_data[31:16]);
accum2 <= tmp_accum2[15:0] + tmp_accum2[16];
tmp_accum1 <= 17'h0;
tmp_accum2 <= 17'h0;
if (ip_data != `IP_ADDRR) begin
//error
end
cnt <= cnt + 16'b1;
end
5: begin
if (options == 1'b0) begin
tmp_accum3 = accum1 + accum2;
final_accum <= tmp_accum3[15:0] + tmp_accum3[16];
if (data_length == 16'h0000) begin
//stop
$display("stop");
end
else if (data_length != 16'h0000) begin
data_length <= data_length - 16'h0001;
ip_data_buffer <= ip_data;
end
end
else if (options == 1'b1) begin
//something with options length here
$display("OPTIONS WERE INCLUDED!");
end
cnt <= cnt + 16'b1;
end
6: begin
if (final_accum != ~checksum) begin
//die
$display("something messed up here: %h %h %h", final_accum, ~checksum, checksum);
end
udp_valid <= 1'b1;
ip_data_buffer <= ip_data;
udp_data <= ip_data_buffer;
data_length <= data_length - 16'h0001;
cnt <= cnt + 16'b1;
end
7: begin
$display("outputing: %h i have %d words left", ip_data_buffer, data_length);
udp_valid <= 1'b1;
ip_data_buffer <= ip_data;
udp_data <= ip_data_buffer;
data_length <= data_length - 16'h0001;
//cnt <= cnt + 16'b1;
end
default: cnt <= 16'h0;
endcase
end
else if (~ivalid) begin
if ((data_length == 16'h0) && (start_data == 1'b1)) begin
if (bufcnt != 1'b0) begin
bufcnt <= bufcnt - 1'b1;
udp_valid <= 1'b1;
udp_data <= ip_data_buffer;
cnt <= 16'b0;
start_data <= 1'b0;
end
/*else if (bufcnt == 1'b0) begin
udp_valid <= 1'b0;
cnt <= 16'b0;
start_data <= 1'b0;
end*/
end
else if ((data_length == 16'h0) && (start_data == 1'b0)) begin
udp_valid <= 1'b0;
end
else if (data_length != 16'h0) begin
udp_valid <= 1'b0;
end
end
end
endmodule
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -