Skip to content

User Manual

IvarNilsson edited this page Aug 5, 2024 · 29 revisions

Welcome to the Acoustic-Warfare FPGA-sampling user manual!
Here is a complete guide to build and run the FPGA-sampler.

Requirements

To be able to build the project some hardware and programs are required.

Hardware

Zybo Z7-20
Microphone array
12-pin PMOD cables
Ethernet cables
Ethernet switch
5V external power supply with a barrel jack connector (coaxial power connector)

Software

Required:
Vivado 2022.1 AS WELL AS Vivado 2017.4 other versions of Vivado will also work but have not been tested on. If you use Vivado 2020.1 or newer Vitis will be used instead of SDK and some changes might be needed.
SDK will be included in Vivado 2017.4.
In this project Vivado 2017.4 will only be used for it's SDK to generate a .elf file and Vivado 2022.1 for building the bitstream. We use two versions since 2022.1 is more stable to build on ubuntu but we dont have disk space for the new vitis so we have to download 2017.4 that have sdk for generating .elf files for the ps logic.

Zsh and Aactivator for sourcing the project's environment.

Recommended:
VSCode or other IDE
WireShark for finding bugs
GHDL, VUnit, GTKWave for testing.

Other good Set-up tips can be found here.

Drivers

Install board files
Linux Cable Drivers

Cloning the github repository

Follow this link for guide on cloning repository.

Beamforming lk

To run the complete system with the beamforming make sure to clone the beamforming-lk repo in the same folder as FPGA-sampling.

Zybo Z7 info

Launching the project and generating a bitstream is slightly different depending on if you use the Zybo Z7-10 or the Z7-20. This wiki explains the process for the Z7-20.

Connecting the hardware

The image highlights the important part of the Zybo that will be used to run this program. Make sure to check:
  1. The blue jumper in the top left corner is set to WALL, when using an external power source.
  2. The other blue jumper in the top right corner is set to JTAG or SD, depending on if you program the FPGA over UDB or using a SD-card.

The Zybo also has integrated LED lights, buttons and switches which for this project has their own purpose:

  • The four LEDs in the middle will indicate how many delays the sampling should have. They are controlled by button 3 (btn3) and button 2 (btn2), shown to the lower middle on the image above. Button 2 increments an index by 1, meaning adding 1 delay to each sample. Button 3 decrements the amount of delays. Maximum 15 delays can be run, at startup 8 delays will be set. The LEDs 0-3 indicates the amount of delays with bits, MSB is shown on ld3 and MSB on ld0. An example: the standard 8 delay will light up ld3 while ld2-0 remains off (bits 1000).
  • Button 1 (btn1) sets the program in different states. At startup the program will run on real data with 2-compliment padding (standard). With one press the program will run a simulated array where the padding is of mic id's. The RBG LED's (ld5 and ld6) will both light red. By pressing btn1 again the state will enter real data where any padding is of mic id's. The RBG LED's ld5 and ld6 will both light yellow. By pressing the button a third time the standard state of real data with two compliment padding will run.
  • The two RGB LEDs (above btn2, in a red box, ld5 and ld6) will indicate how full the FIFO queues are:
    • LD6 being blue symbolizes empty
    • LD6 being green symbolizes almost empty
    • LD5 being red symbolizes almost full
    • LD5 being blue symbolizes full. Mixing of colors can occur, such as purple (almost full and full) and cyan (almost empty and empty).
  • Switch 1 (sw1) and Switch 0 (sw0) is set depending on the number of arrays connected to the FPGA. They are set by bits, meaning sw1 indicates MSB and sw0 LSB. +1 is always added so bits 00 will not set the number of arrays to 0, but 1 instead, meaning we can have 1-4 arrays. An example: if switch 1 on and switch 0 off data will be gathered from 3 arrays (bits 10 = 2, + 1 = 3).
  • Switch 3 (sw3) and switch 2 (sw2) are used to apply an ID to the FPGA, which is used when distributing the system to give them each a unique IP-address. ID's 0-3 can be applied by toggling the switches. They are set by bits, meaning sw3 indicates the MSB and sw2 LSB. An example: switch 3 off and switch 2 on will give the id 2 (bits 01), and thus IP 192.168.1.76 and port 21876. Giving each FPGA their own IP-address happens in main.c.

When the program is running and sending UDP-packets the LED LINK will blink slowly and ACT should blink rapidly, they are placed by the Ethernet port.

The connectors that interfaces with the array are the PMOD connectors. The picture indicates how the pins are configured and if the array is placed with the microphone inputs facing up it should be able to plug straight in to the connector.

To run the program with 4 arrays they need to be placed adjacent to each other with the PMOD pins facing to the left. The arrays are then connected as follows to the Zybo's PMOD ports from right to left (with view of back side of arrays) with the set amount of PMOD cables:

  • Array nr 1 (PCBA 2 DEFECTIVE) to JE, 1 cable
  • Array nr 2 (PCBA 1) to JB, 1 cable
  • Array nr 3 (PCBA 2) to JC, 2 cables
  • Array nr 4 (Version 1) to JD, 3 cables

Startup procedure (using Docker)

Build scripts will handle all of the setup.

Have the Ethernet cable connected between the FPGA and the PC, as well as the power supply.

Running the

build

command will name the generated .bit file (aw_top.bit) as bitstream an place it in the beamforming_lk/boot/tftp directory, as well as the generated .elf file (aw_udp_ps.elf), which needs the name ps.elf. If this didn't occur automatically these files need to be moved and renamed as above.

  • aw_top.bit is in /home/$USER/PROJECT_LOCATION/FPGA-sampling/pl/vivado_files/acoustic_warfare.runs/impl_1
  • aw_udp_ps.elf is in /home/$USER/PROJECT_LOCATION/FPGA-sampling/pl/vivado_files/acoustic_warfare.sdk/aw_udp_ps/Debug/aw_udp_ps.elf

The renaming to bitstream and ps.elf and placing them in the beamforming_lk/boot/tftp directory is crucial for running.

build will also build and run Docker (if not already set up), tftp-server.

There are alternative builds to run if you have partial parts for the program (ex bitstream but no .elf)

build --skip_vivado      Skip Vivado tasks (bitstream)
build --skip_sdk         Skip SDK tasks (.elf)
build --skip_docker      Skip setting up Docker (tftp)
build --vivado_gui       Open Vivado gui    
build --sdk_gui          Open SDK gui    

The latest version of bitstream and ps.elf file can also be found in the releses which means `build can be skipped. Just make sure to have the files in the correct folder and the docker container running, read more about it in the beamforming repo.

Run everything

After connecting the hardware, setting up the bitstream, ps.elf and the tftp docker container, all that remains is turning on the Zybo board. When the program is running and sending UDP-packets correctly the LED LINK will blink slowly and ACT should blink rapidly, they are placed by the Ethernet port.

Process and analyze the data

To have a correct setup for your receiving PC main.c the IP of if may need changes. We used 10.0.0.1 and then match it manually on the receiving computer instead to make the same program able to run on all PCs.

// ip of receiving pc
IP4_ADDR(&ip_remote, 10, 0, 0, 1);

Recommended configuration of receiving PCs IP-address

IPv4 addr: 10.0.0.1 
NET-MASK:  255.255.255.0
GATEWAY:   192.168.1.2

The port is also set in the main file. If wanting to run the repo's receiver (or any other receiver), UDP-receiver it is important that the port number matches the relevant port. Depending on the amount of FPGA's you wish to run with, match with an id (set in Connecting the hardware).

The system can take at most 4 FPGAs, where:

  • Id 0 => IP-address 192.168.1.75 and port 21875
  • Id 1 => IP-address 192.168.1.76 and port 21876
  • Id 2 => IP-address 192.168.1.77 and port 21877
  • Id 3 => IP-address 192.168.1.78 and port 21878

Read from serial port

If you want to read data from a serial port, make sure to have minicom installed and a Micro USB cable connected between the board and PS, and run: sudo minicom -b 115200 -o -D /dev/ttyUSB1

User python receiver

The python script "python_scripts/udp_receiver.py" has two purposes.

  1. It can be used to check the bits sent from the FPGA in a txt file. This can be helpful to see if everything is timed correctly as patterns will appear if there are problems with the delay.
  2. It created an audio file to be used in other python scrips to analyze data.

The script "sound_player.py" allows you to listen to the audio of a mic from the array. Make sure the variables have the right name for your file and run the program. If the sound is extremely noisy there might be a delay problem in the sampling more on that in the troubleshooting section.

Another script for audio files is "analyze_from_file.py". It will plot different graphs of the microphone data. It's recommended to record a sinus wave (500-1000 MHz). Figure 2 and 3 of the script can be helpful in finding malfunctioning microphones on the array.

Troubleshooting

Various problems can occur when trying to launch this program. Here is some help to locate and fix some of the problems.

Vivado problems

Remember to always be gentle to Vivado otherwise you run the risk of upsetting the Vivado gods and you will never be able to build a bitstream again ⚡. Solutions might be illogical and bugs never get fixed but remember some how we have no better alternative. 🎩 ⭐

Vivado not able to config Zynq block

If Vivado is unable to configure the Zynq block in the block design this can be due to the Vivado version used. Vivado 2020.2 on Linux is one of the version that have this problem. However this project should still work since the Zynq block is preconfigured from a .tcl script. If you need a new block design you have to run the auto configuration of zynq block in 2017.4 export the block design to .tcl file, change every mention of vivado version 2017.4 to 2022.1 and then open the tcl block design in vivado 2022.1.

Vivado crashing when trying to generate a bit-stream

This seems to not be a problem on Vivado 2022.1, if it crashes you probably ran out of ram. Try increasing your swap or get a better computer 🖥️ You can try again and set "Number of jobs" to 1 in Vivado or in build_axi_full.tcl. But this do not solve the problem completely.

No data received

If "new_sample_data.txt" (generated from "udp_receiver.py") is empty a good first step is to see if the computer is receiving any UDP-packets. The recommended tool for this is WireShark which will display all the packets received by the computer. If there are no packages showing up here when running the FPGA there is a problem with the UDP-transmitter. A good first test is to do a UDP-ping test. If there is no contact with the FPGA try just a Hello World test to see that the Zynq processor is configured correctly.

If there are packets received by WireShark but no data in the "new_sample_data.txt" file then it is probably a receiver problem. Start by checking that the port in "udp_receiver.py" is the same as in "transmitter_axi_full.c". Else the problem is more likely caused by a firewall or something similar.

Bad data received

Only receiving zeros

There are some things that can cause the receiver to only get zeros. The first is a bad mic-array, if possible try a different array. The second one is a bad WS signal. Try extending the duration of WS in "ws_pulse.vhd" to three pulses long and look at it in a oscilloscope to see that it is a nice square wave with the correct interval.

Noisy and bad sound

If data is received correctly but it is noisy and sounds bad there are a couple of different things to try. The first fix is to lower the sampling frequency. This can be the cause of the problem but in our experience frequency under 16 kHz should not create noisy data. Be aware that if the data is to be used with the Acoustic Warfare beamforming algorithm the frequency should not be lowered.

A second adjustment is to check the delay. A small delay from when WS is activated to when the FPGA start to sample might be needed for optimal result. This can be added in "aw_top.vhd" under the sample_gen_n as "index". To see if a delay is needed and the size of the delay try to use "udp_receiver.py" and search for patterns that creates very big values. If the sampling is of by as little as one bit the data can be completely unusable.

Future work

Some other known problems and future work can be found here.