UCSD ECE 257B Project - Streaming from RFSoc
This repo contains an implementation of our Sliding Window ACK/NACK based Streaming protocol, currently implemented for one way streaming between two PCs. The implementation has abstractions allowing it to be extended in the future to stream between an RFSoC (ZCU111 FPGA) and a PC and zmq+srsRAN.
For ECE 257B Cross-Evaluation, please follow Build, Running the Code, Benchmarking, and Protocol Validation.
Requirements
- Tested for MacOS or Ubuntu
- Streaming
- C++11
- python 3.8+, matplotlib, pandas for plotting
To build the MainStreamer and MainReceiver, run the following, which will generate the Streamer and Receiver executables in x86-64/src
cd x86-64/src
makeTo test the performance of our protocol, we can run Streamer and Receiver with different window sizes and various packet drop probability and monitor the throughput.
cd x86-64/src
make
# Stream 10000 dummy packets on localhost to port 12345, with windowsize 100
./Streamer 127.0.0.1 12345 -num 100000 -window 100
# RUN ME IN A NEW SHELL
# Receive the stream on port 12345
./Receiver 12345 -window 100
# Alternatively, with packet drop probability...
# Receive the stream on port 12345, with 1% of packets dropped (simulating bad channel/congestion)
./Receiver 12345 -window 100 -perror 0.01Running these commands will print the statistics, where you can see the Throughput in Mbps.
Feel free to experiment with various values of window and perror, just ensure the window parameters for Streamer and Receiver match.
Now we can run the benchmarking script to see how probability of error affects the optimal window size, and see what the peak throughput is.
cd x86-64/src
make
cd ../../benchmark
# (delete previous test results, if they exist)
rm -f full_test.csv
# Run the benchmark, with 14 different window sizes and 4 different values of perror
# This should take around 5 mins
python3 benchmark.py
# Plot the results saved in full_test.csv
python3 plot.pyYou should end up with something like this.
To verify the streaming protocol is 100% reliable, we can try streaming a file and verify that the output matches. We can induce random errors to verify that the checksum/NACK mechanism is working as intended, and all data is received correctly even when packets need to be dropped because of low channel quality/congestion.
cd x86-64/src
make all
# Generate a random file
head -c 1000000 </dev/urandom >myfile
# Stream myfile on localhost to port 12345, with windowsize 100
./Streamer 127.0.0.1 12345 -file myfile -window 100
# RUN ME IN A NEW SHELL
# Receive the stream on port 12345, saving the data to outfile, with windowsize 100 and simulated packet drop probability 0.1 (10%)
./Receiver 12345 -file outfile -window 100 -perror 0.1
# Compare the files
diff myfile outfileIf all is well, the diff command will have no output!
./Streamer <receiver_ip> <receiver_port> [-file filename] [-num num_dummy_packets] [-window windowsize] [--debug] [--csv] [--superdumb]- Required:
receiver_ipandreceiver_portdefine the destination of theReceiverof the stream. Use127.0.0.1for localhost/loopback. -file filenamestream from a file-num num_dummy_packetsstream some number of dummy packets (instead of file data)-window windowsizespecify the window size--debugprint debug logs--csvprint statistics as CSV--superdumbdon't generate dummy data, just use the data already in the buffer for max speed
./Receiver <receiver_port> [-file filename] [-perror err] [-window windowsize] [--debug] [--csv]- Required:
receiver_portdefine the port theReceivershould listen on. Must match thereceiver_portfromStreamer -file filenameoutput received data to a file-window windowsizespecify the window size--debugprint debug logs--csvprint statistics as CSV
If you're here, you're most likely looking for the Streaming Protocol Implementation or the benchmarking scripts
MainStreamer.cpp- Top level Stream Sender program for running tests
MainReceiver.cpp- Top level Stream Receiver program for running tests
StreamSender.hpp, StreamSender_impl.hpp- Contains implementation for the Streaming Protocol logic on the sender side, as well as the
StreamSenderinterface. - The
StreamSenderis templated to abstract aDataProviderandNetworkConnection
- Contains implementation for the Streaming Protocol logic on the sender side, as well as the
StreamReceiver.hpp, StreamReceiver_impl.hpp- Contains implementation for the Streaming Protocol logic on the receiver side, as well as the
StreamReceiverinterface. - The
StreamReceiveris templated to abstract aDataProcessorandNetworkConnection
- Contains implementation for the Streaming Protocol logic on the receiver side, as well as the
DataProcessing.hpp- Contains the
DataProviderabstraction for abstracting getting data to streamFileData.hpp : FileReaderreads data from a fileDummyData.hpp : DummyProvidercreates dummy data for testingFPGADataProvider.hpp : FPGADataProviderstub for future implementation of reading RF data on FPGA
- Contains the
DataProcessorabstraction for abstracting what to do with received dataFileData.hpp : FileWriterwrites received data to a fileDummyData.hpp : DummyProcessorprints received data or does nothingZmqDataProcessor.hpp : ZmqDataProcessorpublishes received data to a ZeroMQ socket, for future connection to srsRAN
- Contains the
NetworkConnection.hpp- Contains the
NetworkConnectionabstraction for abstracting sending/receiving data over the networkUDPNetworkConnection.hppUDPStreamSender / UDPStreamReceivercreate simple udp sockets to send packetsFaultyUDPStreamReceiveracts as aUDPStreamReceiver, except has some probability to flip a bit in the received packet, simulating low channel quality or congestion on the channel.
FPGANetworkConnection.hpp : FPGANetworkConnectionstub for future implementation of sending data to Ethernet Subsystem on RFSoC
- Contains the
MainBasicSender.cpp / BasicSender.hppimplement simple TCP streaming using theDataProviderandNetworkConnectionabstractionsMainBasicReceiver.cpp / BasicReceiver.hppimplement simple TCP streaming using theDataProcessorandNetworkConnectionabstractions
- Contains HLS implementation for FPGA of basic data packetization to send to Ethernet Subsystem
- Currently not integrated with Streaming Protocol
ICD.mdContains Interface Control Document for Streaming Protocol- TODO: Rendered in
ICD.pdf
- TODO: Rendered in
- Meeting notes
StreamReceiver.cpp/StreamSender.cppContains initial implementation of the streaming protocol
benchmark.pyContains script for running streaming benchmark with multiple window sizes and different simulated probability of error- Reports result in a
csv
- Reports result in a
plot.pyPlot data fromcsvgenerated bybenchmark.py