From 5e4f4ba2d2078ffb333ae8cee091667dba3aa73e Mon Sep 17 00:00:00 2001 From: David Sidler <david.sidler@inf.ethz.ch> Date: Sun, 15 Dec 2019 23:06:48 -0800 Subject: [PATCH] explanation of TCP interfaces --- README.md | 129 ++++++++++++++++++++++++++++++- waveforms/tcp-rx-handshake.json5 | 19 +++++ waveforms/tcp-tx-handshake.json5 | 16 ++++ 3 files changed, 161 insertions(+), 3 deletions(-) create mode 100644 waveforms/tcp-rx-handshake.json5 create mode 100644 waveforms/tcp-tx-handshake.json5 diff --git a/README.md b/README.md index 6ae414f..5763ad3 100644 --- a/README.md +++ b/README.md @@ -89,8 +89,130 @@ $ make ip $ make installip ``` -## Benchmarks +## Interfaces +All interfaces are using the AXI4-Stream protocol. For AXI4-Streams carrying network/data packets, we use the following definition in HLS: +``` +template <int D> +struct net_axis +{ + ap_uint<D> data; + ap_uint<D/8> keep; + ap_uint<1> last; +}; +``` + +### TCP/IP + +#### Open Connection +To open a connection the destination IP address and TCP port have to provided through the `s_axis_open_conn_req` interface. The TCP stack provides an answer to this request through the `m_axis_open_conn_rsp` interface which provides the sessionID and a boolean indicating if the connection was openend successfully. + +Interface definition in HLS: +``` +struct ipTuple +{ + ap_uint<32> ip_address; + ap_uint<16> ip_port; +}; +struct openStatus +{ + ap_uint<16> sessionID; + bool success; +}; + +void toe(... + hls::stream<ipTuple>& openConnReq, + hls::stream<openStatus>& openConnRsp, + ...); +``` + + + + +#### Close Connection +To close a connection the sessionID has to be provided to the `s_axis_close_conn_req` interface. The TCP/IP stack does not provide a notification upon completion of this request, however it is guranteeed that the connection is closed eventually. + +Interface definition in HLS: +``` +hls::stream<ap_uint<16> >& closeConnReq, + +``` + +#### Open a TCP port to listen on +To open a port to listen on (e.g. as a server), the port number has to be provided to `s_axis_listen_port_req`. The port number has to be in range of active ports: 0 - 32767. The TCP stack will respond through the `m_axis_listen_port_rsp` interface indicating if the port was set to the listen state succesfully. + +Interface definition in HLS: +``` +hls::stream<ap_uint<16> >& listenPortReq, +hls::stream<bool>& listenPortRsp, +``` +#### Receiving notifications from the TCP stack +The application using the TCP stack can receive notifications through the `m_axis_notification` interface. The notifications either indicate that new data is available or that a connection was closed. + +Interface definition in HLS: +``` +struct appNotification +{ + ap_uint<16> sessionID; + ap_uint<16> length; + ap_uint<32> ipAddress; + ap_uint<16> dstPort; + bool closed; +}; + +hls::stream<appNotification>& notification, +``` + +#### Receiving data +If data is available on a TCP/IP session, i.e. a notification was received. Then this data can be requested through the `s_axis_rx_data_req` interface. The data as well as the sessionID are then received through the `m_axis_rx_data_rsp_metadata` and `m_axis_rx_data_rsp` interface. + +Interface definition in HLS: +``` +struct appReadRequest +{ + ap_uint<16> sessionID; + ap_uint<16> length; +}; + +hls::stream<appReadRequest>& rxDataReq, +hls::stream<ap_uint<16> >& rxDataRspMeta, +hls::stream<net_axis<WIDTH> >& rxDataRsp, +``` + +Waveform of receiving a (data) notification, requesting data, and receiving the data: + + + + +#### Transmitting data +When an application wants to transmit data on a TCP connection, it first has to check if enough buffer space is available. This check/request is done through the `s_axis_tx_data_req_metadata` interface. If the response through the `m_axis_tx_data_rsp` interface from the TCP stack is positive. The application can send the data through the `s_axis_tx_data_req` interface. If the response from the TCP stack is negative the application can retry by sending another request on the `s_axis_tx_data_req_metadata` interface. + +Interface definition in HLS: +``` +struct appTxMeta +{ + ap_uint<16> sessionID; + ap_uint<16> length; +}; +struct appTxRsp +{ + ap_uint<16> sessionID; + ap_uint<16> length; + ap_uint<30> remaining_space; + ap_uint<2> error; +}; + +hls::stream<appTxMeta>& txDataReqMeta, +hls::stream<appTxRsp>& txDataRsp, +hls::stream<net_axis<WIDTH> >& txDataReq, +``` + +Waveform of requesting a data transmit and transmitting the data. + + + +## Benchmarks +(Coming soon) ## Publications @@ -122,7 +244,8 @@ If you use the TCP/IP stack in your project please cite one of the following pap ``` ## Contributors -- [David Sidler](http://github.com/dsidler), [Systems Group] (http://systems.ethz.ch), ETH Zurich +- [David Sidler](http://github.com/dsidler), [Systems Group](http://systems.ethz.ch), ETH Zurich +- [Monica Chiosa](http://github.com/chipet), [Systems Group](http://systems.ethz.ch), ETH Zurich - [Mario Ruiz](https://github.com/mariodruiz), HPCN Group of UAM, Spain -- [Kimon Karras] (http://github.com/kimonk), former Researcher at Xilinx Research, Dublin +- [Kimon Karras](http://github.com/kimonk), former Researcher at Xilinx Research, Dublin - [Lisa Liu](http://github.com/lisaliu1), Xilinx Research, Dublin diff --git a/waveforms/tcp-rx-handshake.json5 b/waveforms/tcp-rx-handshake.json5 new file mode 100644 index 0000000..15d79ba --- /dev/null +++ b/waveforms/tcp-rx-handshake.json5 @@ -0,0 +1,19 @@ +{signal: [ + {name: 'axi_clk', wave: 'p...|...|......'}, + {name: 'm_axis_notification_valid', wave: '0.10|...|......'}, + {name: 'm_axis_notification_ready', wave: '1...|...|......'}, + {name: 'm_axis_notification_data', wave: 'x.=x|...|......', data: ['ID,length']}, + {name: 's_axis_rx_data_req_valid', wave: '0...|.10|......'}, + {name: 's_axis_rx_data_req_ready', wave: '0..1|..0|......'}, + {name: 's_axis_rx_data_req_data', wave: 'x...|.=x|......', data: ['ID,length']}, + {name: 'm_axis_rx_data_rsp_metadata_valid', wave: '0...|...|.10...'}, + {name: 'm_axis_rx_data_rsp_metadata_ready', wave: '1...|...|......'}, + {name: 'm_axis_rx_data_rsp_metadata_data', wave: 'x...|...|.=x...', data: ['ID']}, + {name: 'm_axis_rx_data_rsp_valid', wave: '0...|...|.1..0.'}, + {name: 'm_axis_rx_data_rsp_ready', wave: '1...|...|......'}, + {name: 'm_axis_rx_data_rsp_data', wave: 'x...|...|.===x.', data: ['D0', 'D1', 'D2']}, + {name: 'm_axis_rx_data_rsp_keep', wave: 'x...|...|.===x.', data: ['FF', 'FF', '0F']}, + {name: 'm_axis_rx_data_rsp_last', wave: '0...|...|...10.'}, +], +config: { hscale: 1.5 } +} \ No newline at end of file diff --git a/waveforms/tcp-tx-handshake.json5 b/waveforms/tcp-tx-handshake.json5 new file mode 100644 index 0000000..9225965 --- /dev/null +++ b/waveforms/tcp-tx-handshake.json5 @@ -0,0 +1,16 @@ +{signal: [ + {name: 'axi_clk', wave: 'p..|...|....'}, + {name: 's_axis_tx_data_req_metadata_valid', wave: '010|...|....'}, + {name: 's_axis_tx_data_req_metadata_ready', wave: '1..|...|....'}, + {name: 's_axis_tx_data_req_metadata_data', wave: 'x=x|...|....', data: ['ID,length']}, + {name: 'm_axis_tx_data_rsp_valid', wave: '0..|.10|....'}, + {name: 'm_axis_tx_data_rsp_ready', wave: '1..|...|....'}, + {name: 'm_axis_tx_data_rsp_data', wave: 'x..|.=x|....', data: ['ID,error']}, + {name: 's_axis_tx_data_req_valid', wave: '0..|...|10..'}, + {name: 's_axis_tx_data_req_ready', wave: '1..|...|....'}, + {name: 's_axis_tx_data_req_data', wave: 'x..|...|===x', data: ['D0', 'D1', 'D2']}, + {name: 's_axis_tx_data_req_keep', wave: 'x..|...|===x', data: ['FF', 'FF', '0F']}, + {name: 's_axis_tx_data_req_last', wave: '0..|...|..10'}, +], +config: { hscale: 1.5 } +} \ No newline at end of file -- GitLab