RENEW Project Documentation

Version 1.0

Reconfigurable Ecosystem for Next-generation End-to-end Wireless

Sounder

Sounder provides a framework to record the received signal from all clients at all antennas in the massive MIMO base station. This includes orthogonal pilot signals from each configured client and uplink signals sent at common subframes by those clients. These signals are recorded as multi-dimensional matrices in HDF5 format. The recorded files can then be analyzed with RENEW python tools for various statistics and channel behavior analysis as well as offline demultiplexing of the uplink signals.

The same binary can be used to configure all SDRs in the base station as well as all clients. The configuration is defined in json format and passed as an input argument to the binary.

In this document, we provide an extensive tutorial on the configuration and usage of the Sounder framework. First, let’s look at how to build the code.

Build the code

There are a few dependencies for running this code base. This includes muFFT and C++ json library. The following script install all dependencies and build the code.

$ ./install_cclibs.sh
$ cmake ./
$ make -j

Once the code builds successfully, you’ll get a binary sounder executable in the same folder. Now let’s start looking at the configuration file and editing it. Some sample configuration files are in files.

Open tddconfig.json. You see two json tags, BaseStations and Clients. Let’s look at BaseStations first:

  • cells determines how many BaseStations and therefore physical cells are used in the experiment. Currently only a single cell is supported.
  • hub id specifies the file name containing the list of hub serials used at all BaseStations. Each hub serial must be listed in a separate line. Note, a hub device is used to trigger all SDRs in a BaseStation.
  • sdr id specifies the list of filenames including SDR serial numbers for each BaseStation. An example of such file is in the files directory. Serial numbers must be listed with one serial per line. If hub serial file is empty the first sdr serial in sdr id file is used to trigger the reset of the devices. This only work if only a single daisy-chained SDR array is used. In this case, you have to make sure the first SDR serial in the sdr id file is the first physical SDR in the daisy-chain. For more information on this, please see the Hardware section
  • frequency sets the band the SDRs will operate on. The driver accepts the range [30e6-3800e6] Hz, but the usable range depends on the flavor of the base station (front-end type and antenna).
  • rate set the sample rate on the channel of all SDRs. Current hardware supported range for sample rate is 1-40MHz.

  • polarization allows you to choose either single, or dual polarization configurations. Note, each SDR in the base station has two TX/RX channels (A and B) and each one is attached to different a different antenna polarization. So, this key also determines the number of antennas used in the BaseStation during the experiment. In single mode, only channel A is used.

  • rxgainA, txgainA, rxgainB, txgainB set the RX and TX gains on each SDR channel respectively. Current ranges for RX gain and TX gain are [0,30] and [0,52] respectively.

  • frame schedule defines the structure of a TDD frame that will be followed during the experiment. Details on the TDD framer and its configuration, can be found in the python design flow. The difference here is the letters are changed to unify the config for both BaseStation and Clients. ‘B’ represents a subframe used to broadcast beacons from the base station. ‘P’ represents a pilot subframe that is transmitted by Client and received by the BaseStation. ’D’ and ‘U’ represent Downlink and uplink frames respectively. ‘G’ is kept as default (Guard interval or no TX or RX by anyone). The schedule is configured on all BaseStation SDR at the beginning of experiment.

  • frame mode defines the frame counting mode. For the base station, this is set to free_running.

  • subframe size specifies the number of samples in each subframe (generic symbol). Each subframe can include multiple OFDM symbols.

  • fft size defines the size of fft used for OFDM symbol in subframes.

  • cp size defines the cyclic prefix size for each OFDM symbol.

  • prefix specifies the number of padding samples in the beginning of each subframe.

  • postfix specifies the number of padding samples at the end of each subframe.

  • beacon seq selects from multiple existing pseudo-noise sequences. Currently only “gold ifft” is supported.

  • beamsweep specifies whether the beacons are beamsweeped using open-loop precoding. If true, M hadamard sequences are generated, with M being the number of antennas, and sent to all SDRs to be applied duing the beacon subframe. This way M distinguished beacon beams are generated in every M consecutive frames.

  • beacon antenna is used when beamsweep is false. In this case only the identified antenna index at the BaseStation is used to send the beacon.

  • pilot seq selects from multiple existing signal types. Currently only “lts” is supported.

"BaseStations" : {
         "cells" : 1,
         "hub_id" : "conf/hub_serials.txt",
         "sdr_id" : ["conf/iris_serials.txt"],
         "frequency" : 3.6e9,
         "rate" : 5e6,
         "polarization" : "single",
         "rxgainA" : 20,
         "txgainA" : 40,
         "rxgainB" : 20,
         "txgainB" : 40,
         "frame_schedule" : [
             "BGPPUGGGGGGGGGGGGGGG"
         ],
         "frame_mode" : "free_running",
         "subframe_size" : 400,
         "fft_size" : 64,
         "cp_size" : 16,
         "prefix" : 82,
         "postfix" : 68,
         "beacon_seq" : "gold_ifft",
         "beamsweep" : false,
         "beacon_antenna" : 0,
         "pilot_seq" : "lts"
}
  • sdr id specifies the list of SDR serial numbers for each Client.
  • frequency same as BaseStation.

  • polarization same as BaseStation

  • rxgainA, txgainA, rxgainB, txgainB same as BaseStation

  • rate same as BaseStation

  • frame schedule same as BaseStation except ‘B’ is not used for Clients and the equivalent subframe as ‘B’ in the BaseStation is set as ‘G’ for all clients. During this subframe the internal correlator at the Clients, tries to detect the beacon and set the frame time accordingly to synchronize with the BaseStation. Note, each Clients needs its own schedule and the number of array entries must match the number of Client serial numbers in the sdr id key. Additionally if ‘U’ or uplink is used, make sure you include a ’D’ or Downlink subframe in the schedule. This will act as a dummy receive so the transmit streaming (for uplink) can use the timestamps from receive (downlink) stream. Since this is a dummy receive, the corresponding subframe at the BaseStation is just a Guard interval.

  • frame mode defines the frame counting mode. For the clients, this is set to either “continuous_resync” or “triggered”. In “triggered” mode, clients wait to receive a beacon to start a new frame. In “continuous_resync” mode, clients keep counting frames after the first received beacon and upon detection of every new beacon they resync their time to a preset value (symbol number/sample number). The preset value is set during setup using “setHardwareTime” Soapy function. This means that if a beacon is missed, client still sends pilots and data.

  • subframe size specifies the number of samples in each subframe (generic symbol). Each subframe can include multiple OFDM symbols.

  • fft size defines the size of fft used for OFDM symbol in subframes.

  • cp size defines the cyclic prefix size for each OFDM symbol.

  • prefix specifies the number of padding samples in the beginning of each subframe.

  • postfix specifies the number of padding samples at the end of each subframe.

  • agc en will enable the AGC logic in the clients. For more details on AGC see [here]

  • beacon seq selects from multiple existing pseudo-noise sequences. Currently only “gold ifft” is supported. The sequence is used to fill in the correlator taps implemented at the Clients.

  • modulation specifies the type the modulation in used in the uplink data.

  • pilot seq selects from multiple existing signal types. Currently only “lts” is supported. Corresponding pilot signal is sent by each Client during its designated pilot subframe.

"Clients" : {
         "sdr_id" : [
             "RF3E000029",
             "RF3E000040"
         ],
         "frequency" : 3.6e9,
         "rate" : 5e6,
         "polarization" : "single",
         "rxgainA" : 20,
         "txgainA" : 40,
         "rxgainB" : 20,
         "txgainB" : 40,
         "frame_schedule" : [
             "GDPGUGGGGGGGGGGGGGGG",
             "GDGPUGGGGGGGGGGGGGGG"
         ],
         "frame_mode" : "continuous_resync",
         "subframe_size" : 400,
         "fft_size" : 64,
         "cp_size" : 16,
         "prefix" : 82,
         "postfix" : 68,
         "agc_en" : false,
         "beacon_seq" : "gold_ifft",
         "pilot_seq" : "lts",
         "modulation" : "QPSK"
}

Edit the above configuration according to your desired experiment setup. Make sure, BaseStation and Client configurations match so that your experiment runs properly. In particular, pay close attention to the schedules for all Clients and the BaseStation. To run the experiment

$ ./sounder files/tddconfig.json

With running above, the framework starts recording the received raw samples in HDF5 file in the logs/ directory. Below is a sample shell output:

Set HDF5 File to logs/Argos-2019-2-18-15-23-21_1x8x2.hdf5 and group to /
dim pilot chunk = 5
New Pilot Dataset Dimension 5,2000,1,2,8,1100
dim data chunk = 5
New Data Dataset Dimension 5,2000,1,1,8,1100
PGRRRGGGGGGGGGGGGGGG
[INFO] Wrote TDD config: symbol_size=550, num_frames=1, trigger_out=0, wait_trigger=0, dual_pilot=0, max_frame=0
[INFO] Wrote TDD config: symbol_size=550, num_frames=1, trigger_out=0, wait_trigger=0, dual_pilot=0, max_frame=0
[INFO] Wrote TDD config: symbol_size=550, num_frames=1, trigger_out=0, wait_trigger=0, dual_pilot=0, max_frame=0
[INFO] Wrote TDD config: symbol_size=550, num_frames=1, trigger_out=0, wait_trigger=0, dual_pilot=0, max_frame=0
[INFO] Wrote TDD config: symbol_size=550, num_frames=1, trigger_out=0, wait_trigger=0, dual_pilot=0, max_frame=0
[INFO] Wrote TDD config: symbol_size=550, num_frames=1, trigger_out=0, wait_trigger=0, dual_pilot=0, max_frame=0
[INFO] Wrote TDD config: symbol_size=550, num_frames=1, trigger_out=0, wait_trigger=0, dual_pilot=0, max_frame=0
[INFO] Wrote TDD config: symbol_size=550, num_frames=1, trigger_out=0, wait_trigger=0, dual_pilot=0, max_frame=0
waiting for receive frames... 
waiting for receive frames... 
[WARNING] Could not set thread priority 1.0 in acquireWriteBuffer: Operation not permitted
[WARNING] Could not set thread priority 1.0 in acquireWriteBuffer: Operation not permitted
package receiver thread 3 start
pinning thread 3 to core 4
package receiver thread 2 start
pinning thread 2 to core 3
receiver thread 3 has 2 radios
[WARNING] Could not set thread priority 1.0 in acquireReadBuffer: Operation not permitted
receiver thread 2 has 2 radios
[WARNING] Could not set thread priority 1.0 in acquireReadBuffer: Operation not permitted
package receiver thread 1 start
pinning thread 1 to core 2
package receiver thread 0 start
pinning thread 0 to core 1
receiver thread 0 has 2 radios
receiver thread 1 has 2 radios
[WARNING] Could not set thread priority 1.0 in acquireReadBuffer: Operation not permitted
[WARNING] Could not set thread priority 1.0 in acquireReadBuffer: Operation not permitted
FrameId 2000, (Pilot) Extent to 2400 Frames
(Data) Extent to 2400 Frames
Closing HDF5, 2001 frames saved.
dim pilot chunk = 5
New Pilot Dataset Dimension 5,2000,1,2,8,1100
dim data chunk = 5
New Data Dataset Dimension 5,2000,1,1,8,1100

Stop the recording with Ctrl+C at any time. Use the tools in Python design flow to read back and analyze the output HDF5 file.


Last updated on 16 May 2019 / Published on 12 Feb 2019