Skip to content
Snippets Groups Projects
Commit 7ebbef48 authored by Byron Lathi's avatar Byron Lathi
Browse files

Get a full tcp handshake, send data, and close cleanly

parent 766fe72d
No related branches found
No related tags found
2 merge requests!77Calculate checksum for tcp data also,!74Resolve "Network Processor"
Pipeline #765 passed
from http import server
from turtle import xcor
from scapy.layers.inet import Ether, IP, TCP
from scapy.layers.l2 import ARP
from scapy.data import IP_PROTOS
......@@ -107,7 +108,7 @@ async def test_irl(dut):
serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
serversocket.bind((tb_ip, 5678))
serversocket.listen(5)
serversocket.listen(1)
t = TunTapInterface('tun0')
......@@ -176,7 +177,10 @@ async def test_irl(dut):
t.send(ip_packet)
pkt = t.recv()
while True:
pkt = t.recv()
if (pkt.proto == IP_PROTOS.tcp):
break
print(pkt)
tcp_synack = Ether(dst=dut_mac, src=tb_mac) / pkt
......@@ -206,6 +210,28 @@ async def test_irl(dut):
con, addr = serversocket.accept()
# Construct a descriptor in memry
tb.axil_ram.write_dword(0x00000000, 0x00001000)
tb.axil_ram.write_dword(0x00000004, 64)
tb.axil_ram.write_dword(0x00000008, 0)
tb.axil_ram.write_dword(0x0000000c, 0)
test_data = bytearray([x % 256 for x in range(256)])
tb.axil_ram.write(0x1000, test_data)
await tb.axil_master.write_dword(0x22c, 0)
await tb.axil_master.write_dword(0x220, 0x00000000)
await tb.axil_master.write_dword(0x224, 0x00000000)
resp = await tb.mii_phy.tx.recv() # type: GmiiFrame
packet = Ether(resp.get_payload())
t.send(packet.payload)
con.recv(64)
tb.log.info("Received 64 packets")
con.close()
serversocket.close()
......@@ -215,6 +241,18 @@ async def test_irl(dut):
break
print(pkt)
tcp_ack = Ether(dst=dut_mac, src=tb_mac) / pkt
await tb.mii_phy.rx.send(GmiiFrame.from_payload(tcp_ack.build()))
tb.log.info("Expecting to send an F here")
while True:
pkt = t.recv()
if (pkt.proto == IP_PROTOS.tcp):
break
print(pkt)
tcp_fin = Ether(dst=dut_mac, src=tb_mac) / pkt
await tb.mii_phy.rx.send(GmiiFrame.from_payload(tcp_fin.build()))
......@@ -240,31 +278,16 @@ async def test_irl(dut):
t.send(ip_packet)
return
# Construct a descriptor in memry
tb.axil_ram.write_dword(0x00000000, 0x00001000)
tb.axil_ram.write_dword(0x00000004, 64)
tb.axil_ram.write_dword(0x00000008, 0)
tb.axil_ram.write_dword(0x0000000c, 0)
test_data = bytearray([x % 256 for x in range(256)])
tb.axil_ram.write(0x1000, test_data)
tb.log.info("Expecting to send last ACK here")
while True:
pkt = t.recv()
if (pkt.proto == IP_PROTOS.tcp):
break
print(pkt)
await tb.axil_master.write_dword(0x22c, 0)
await tb.axil_master.write_dword(0x220, 0x00000000)
await tb.axil_master.write_dword(0x224, 0x00000000)
resp = await tb.mii_phy.tx.recv() # type: GmiiFrame
packet = Ether(resp.get_payload())
t.send(packet.payload)
tcp_fin = Ether(dst=dut_mac, src=tb_mac) / pkt
# con.recv(64)
await tb.mii_phy.rx.send(GmiiFrame.from_payload(tcp_fin.build()))
serversocket.close()
await Timer(Decimal(CLK_PERIOD_NS * 1000), units='ns')
......@@ -4,6 +4,8 @@ module tcp_packet_generator (
axis_intf.SLAVE s_axis_data,
input wire i_no_data,
input wire [15:0] i_ip_len,
input wire [31:0] i_seq_number,
input wire [31:0] i_ack_number,
......@@ -21,8 +23,33 @@ module tcp_packet_generator (
ip_intf.MASTER m_ip
);
axis_intf #(.DATA_WIDTH(8)) pre_checksum_data();
axis_intf #(.DATA_WIDTH(8)) post_checksum_data();
logic saf_ready;
assign pre_checksum_data.tdata = s_axis_data.tdata;
assign pre_checksum_data.tkeep = s_axis_data.tkeep;
assign pre_checksum_data.tvalid = s_axis_data.tvalid & saf_ready;
assign s_axis_data.tready = pre_checksum_data.tready & saf_ready;
assign pre_checksum_data.tlast = s_axis_data.tlast;
assign pre_checksum_data.tuser = s_axis_data.tuser;
axis_saf_fifo #(
.DATA_DEPTH_L2(11),
.CTRL_DEPTH_L2(1)
) u_checksum_fifo (
.sclk(i_clk),
.srst(i_rst),
.s_axis(pre_checksum_data),
.mclk(i_clk),
.mrst(i_rst),
.m_axis(post_checksum_data)
);
logic [31:0] counter, counter_next;
enum logic [1:0] {IDLE, HEADER, DATA} state, state_next;
enum logic [1:0] {IDLE, DATA_CHECKSUM, HEADER, DATA} state, state_next;
logic [31:0] checksum_counter, checksum_counter_next;
......@@ -34,7 +61,13 @@ logic checksum_clear;
logic [31:0] checksum_data;
logic [15:0] checksum_final;
checksum_calc u_checksum_calc(
logic [31:0] data_expand, data_expand_next;
logic data_checksum_enable;
logic data_checksum_clear;
logic [31:0] data_checksum_data;
logic [15:0] data_checksum_final;
checksum_calc u_header_checksum_calc(
.i_rst (i_rst),
.i_clk (i_clk),
.i_clear (checksum_clear),
......@@ -49,10 +82,12 @@ always_ff @(posedge i_clk) begin
counter <= '0;
checksum_counter <= '0;
state <= IDLE;
data_expand <= '0;
end else begin
counter <= counter_next;
checksum_counter <= checksum_counter_next;
state <= state_next;
data_expand <= data_expand_next;
end
end
......@@ -64,6 +99,10 @@ always_comb begin
checksum_clear = '0;
checksum_enable = '0;
saf_ready = '0;
data_expand_next = data_expand;
case (state)
IDLE: begin
......@@ -82,7 +121,32 @@ always_comb begin
m_ip.ip_dest_ip = i_dst_ip;
if (m_ip.ip_hdr_ready) begin
if (i_no_data) begin
state_next = HEADER;
end else begin
state_next = DATA_CHECKSUM;
end
end
end
end
DATA_CHECKSUM: begin
saf_ready = '1;
data_expand_next = {data_expand[23:0], pre_checksum_data.tdata};
// data_expand_next = {pre_checksum_data.tdata, data_expand[31:8]};
if (checksum_counter[1:0] == '1) begin
checksum_enable = '1;
checksum_data = data_expand_next;
end
if (s_axis_data.tready & s_axis_data.tvalid) begin
checksum_counter_next = checksum_counter + 1;
if (s_axis_data.tlast) begin
state_next = HEADER;
checksum_counter_next = '0;
end
end
end
......@@ -97,7 +161,7 @@ always_comb begin
case (checksum_counter)
0: checksum_data = m_ip.ip_source_ip;
1: checksum_data = m_ip.ip_dest_ip;
2: checksum_data = {8'b0, m_ip.ip_protocol, 16'd20}; // tcp length, not IP length
2: checksum_data = {8'b0, m_ip.ip_protocol, (i_ip_len - 16'd20)}; // tcp length, not IP length
3: checksum_data = {i_source_port, i_dest_port};
4: checksum_data = i_seq_number;
5: checksum_data = i_ack_number;
......@@ -127,7 +191,7 @@ always_comb begin
18: m_ip.ip_payload_axis_tdata = '0;
19: begin
m_ip.ip_payload_axis_tdata = '0;
m_ip.ip_payload_axis_tlast = ~s_axis_data.tvalid; // kinda hacky
m_ip.ip_payload_axis_tlast = i_no_data; // kinda hacky
end
endcase
......@@ -147,12 +211,12 @@ always_comb begin
DATA: begin
state_next = DATA;
s_axis_data.tready = m_ip.ip_payload_axis_tready;
m_ip.ip_payload_axis_tvalid = s_axis_data.tvalid;
m_ip.ip_payload_axis_tdata = s_axis_data.tdata;
m_ip.ip_payload_axis_tlast = s_axis_data.tlast;
post_checksum_data.tready = m_ip.ip_payload_axis_tready;
m_ip.ip_payload_axis_tvalid = post_checksum_data.tvalid;
m_ip.ip_payload_axis_tdata = post_checksum_data.tdata;
m_ip.ip_payload_axis_tlast = post_checksum_data.tlast;
if (s_axis_data.tlast && s_axis_data.tvalid && s_axis_data.tready) begin
if (post_checksum_data.tlast && post_checksum_data.tvalid && post_checksum_data.tready) begin
state_next = IDLE;
o_packet_done = '1;
end
......
......@@ -43,7 +43,13 @@ always_comb begin
o_rx_msg = RX_MSG_RECV_FIN;
o_rx_msg_valid = '1;
end
if (i_flags == 8'h10) begin
o_rx_msg = RX_MSG_RECV_ACK;
o_rx_msg_valid = '1;
end
end
end
endmodule
\ No newline at end of file
endmodule
......@@ -50,6 +50,7 @@ always_comb begin
tcp_state_next = tcp_state;
o_tx_ctrl_valid = '0;
o_open_clr = '0;
o_tx_ctrl = TX_CTRL_NOP;
o_tx_ctrl_valid = '0;
......@@ -80,6 +81,7 @@ always_comb begin
if (i_tx_ctrl_ack) begin
tcp_state_next = ESTABLISHED;
o_open_clr = '1;
end
end
......@@ -92,9 +94,11 @@ always_comb begin
end
LAST_ACK: begin
if (i_rx_msg_valid && i_rx_msg == RX_MSG_RECV_ACK) begin
tcp_state_next = IDLE;
end
end
endcase
end
endmodule
\ No newline at end of file
endmodule
......@@ -49,6 +49,8 @@ tcp_pkg::rx_msg_t rx_msg;
logic rx_msg_valid;
logic rx_msg_ack;
logic w_no_data;
logic [15:0] w_saf_pkt_len;
logic [15:0] w_tx_ip_len;
logic [31:0] w_tx_seq_number;
......@@ -166,6 +168,7 @@ tcp_tx_ctrl u_tcp_tx_ctrl (
.i_tx_ctrl_valid (tx_ctrl_valid),
.o_tx_ctrl_ack (tx_ctrl_ack),
.o_no_data (w_no_data),
.o_ip_len (w_tx_ip_len),
.o_seq_number (w_tx_seq_number),
// .o_ack_number (w_tx_ack_number),
......@@ -187,6 +190,7 @@ tcp_packet_generator u_tcp_packet_generator (
.s_axis_data (m_tx_ctrl_axis_data),
.i_no_data (w_no_data),
.i_ip_len (w_tx_ip_len),
.i_seq_number (w_tx_seq_number),
.i_ack_number (w_tx_ack_number),
......@@ -238,4 +242,4 @@ tcp_rx_ctrl u_tcp_rx_ctrl (
// rx buffer
endmodule
\ No newline at end of file
endmodule
......@@ -8,6 +8,8 @@ module tcp_tx_ctrl(
input logic i_tx_ctrl_valid,
output logic o_tx_ctrl_ack,
output logic o_no_data,
output logic [15:0] o_ip_len,
output logic [31:0] o_seq_number,
output logic [31:0] o_ack_number,
......@@ -57,10 +59,11 @@ end
always_comb begin
state_next = state;
o_no_data = '0;
o_ack_number = '0;
o_flags = '0;
o_window_size = 16'b1;
o_window_size = 16'h100;
o_hdr_valid = '0;
seq_num_next = seq_num;
......@@ -86,6 +89,7 @@ always_comb begin
SEND_SYN: begin
o_flags = FLAG_SYN;
o_no_data = '1;
o_hdr_valid = '1;
if (i_packet_done) begin
......@@ -96,6 +100,7 @@ always_comb begin
SEND_ACK: begin
o_flags = FLAG_ACK;
o_no_data = '1;
o_hdr_valid = '1;
if (i_packet_done) begin
......@@ -106,6 +111,7 @@ always_comb begin
SEND_DATA: begin
o_flags = FLAG_ACK | FLAG_PSH;
o_no_data = '0;
o_ip_len = 16'd40 + s_axis_len; // default length of IP packet
o_hdr_valid = '1;
......@@ -117,7 +123,8 @@ always_comb begin
SEND_FIN: begin
o_flags = FLAG_ACK | FLAG_FIN;
o_ip_len = 16'd40 + s_axis_len; // default length of IP packet
o_no_data = '1;
o_ip_len = 16'd40; // default length of IP packet
o_hdr_valid = '1;
if (i_packet_done) begin
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment