Modifying FPGA gateware to reduce packet size

Hi all,

In this thread I describe in detail the application I am working on. In summary, it’s possible that the FPGA packet size of 1020 samples may be increasing the latency too much for my application (an RFID reader), so I’m looking to reduce it in order to try and bring down the latency due to the packet having to be filled up before sending it down USB3.

It was suggested in the other thread by @IgnasJ that to reduce the FPGA packet size I would need to edit the FPGA gateware. However, this is going to be quite difficult for me to do, for a number of reasons (given below), principally my lack of experience and time…

I don’t suppose anyone has needed to modify the gateware to reduce the packet size (or the latency in general) already, or could produce a set of gateware which I could use, if it’s a relatively simple change for someone who knows what they’re doing?

I really hate to ask for other people to do things for me as I enjoy learning and understanding things, but in this circumstance there are the following reasons:

  • I have no prior experience with FPGAs
  • I am restricted with the time I can spend. I am a final year university student (implementing an RFID reader with the LimeSDR is my final year project), so unfortunately the demands of the rest of my course and the fact that this project is assessed mean that it’s quite risky (for my grade) to devote a lot of time learning about FPGAs, and the Lime gateware specifically, to try something which may not fix my issue anyway.
  • Even if I did try to fiddle with the gateware, I’m worried about bricking the Lime by putting gateware which doesn’t work on the FPGA, especially given that I’d be fiddling with stuff which affects USB transfers. Perhaps this isn’t a valid concern - is it always possible to overwrite the existing gateware with a new, working version, regardless of what the current gateware is?

If it’s any incentive, the research group I am working with might be tempted to buy a few more LimeSDRs if I’m able to get the RFID reader working with the Lime, as it has a few properties which might make it quite a good RFID reader if this latency issue can be resolved.

Alternatively, if someone could at least point me in the right direction in terms of where I need to be looking to modify the FPGA packet size, that would also be really helpful!

Thanks and regards,
DasSidG

I believe so, yes, as it just lives in flash and is loaded each time upon power up. Even if you put bad firmware into the FX3 you can remove a jumper so that it runs a factory/ROM firmware which allows you to load a new image.

I don’t think you should worry about bricking your board.

You might want to load the FX3 USB firmware using USB each time you start.

The lime is set up to boot from flash. In Linux it will appear as:

$ lsusb -s 2:3
Bus 002 Device 003: ID 1d50:6108 OpenMoko, Inc. Myriad-RF LimeSDR

If you remove the J13 jumper you will observe:

$ lsusb -s 1:7
Bus 001 Device 007: ID 04b4:00f3 Cypress Semiconductor Corp.

You’re now in the FX3 default state and can re-load the FX3 firmware:

sudo fxload -t fx3 -i LimeSDR-USB_FX3.git/Debug/LimeSDR-USB_fx3_fw.img

Note that there are different versions of fxload around so the command line above might be different for some systems. See Just trying to get started, having no luck

Then you have a new fresh FX3 firmware stored in the FX3 RAM ready for use
$ lsusb -s 2:6
Bus 002 Device 006: ID 1d50:6108 OpenMoko, Inc. Myriad-RF LimeSDR

On the FPGA side you can use a USB blaster and a conversion cable to fit the small J11 FPGA JTAG connector (described in J11 FPGA JTAG connector?). This might come handy if you have to debug the FPGA with signaltap.

You can then load the FPGA configuration into the FPGA using:

$ quartus_pgm -c 'USB-Blaster [1-3]' -m jtag -o p\;./output_files/LimeSDR-USB_lms7_trx_HW_1.4.sof

For the purpose of illustration I’ve made a FX3 and FPGA image with a different version numbers. LimeUtil will detect this:

$ LimeUtil --make
Make device 
[WARNING] Firmware version mismatch!
  Expected firmware version 3, but found version 4
...
[WARNING] Gateware version mismatch!
  Expected gateware version 2, revision 9
  But found version 2, revision 15
...
  Firmware version: 4
  Hardware version: 4
  Protocol version: 1
  Gateware version: 2
  Gateware revision: 15
...

If you use the above method you don’t write the FX3 firmware in the on-board FLASH so a power cycle and re-connect of the J13 you will be back to normal again.

When doing FPGA design it’s common to do the bulk of the design and debugging using simulation (there’s a free/reduced version of Modelsim in the Altera distribution). However, it might be some effort to make a testbench with a FX3 model if you don’t have any experience with FPGAs. On the other hand it might be as simple as changing a queue size constant. I don’t know, I haven’t checked. It might even be that there is a queue size register which can be written for what I know. Perhaps some of the designers can give you a hint.

2 Likes

Hi zener,

Thanks for your detailed reply, I really appreciate it! You and andrew have allayed my fears about bricking the board. Unfortunately due to time constraints I think I will still mostly have to give up on reducing the latency using this method, as I can’t really afford to spend the time getting to grips with the FPGA programming at the moment. Apologies for wasting your time; hopefully others will find the above info useful.

Hello everyone,
I also came across the same issue since the project I am currently working on requires low latency and I am using lower sampling rate, so I decided to reduce the FPGA data packet size. I have recently started working on the Gateware, modified the TX and PX path to change the FPGA packet size to 1024 bytes with 252 samples in each sample packet. The new gateware code can be found at my branch.

These software changes needs to be made:

— a/src/protocols/dataTypes.h
+++ b/src/protocols/dataTypes.h
@@ -10,7 +10,7 @@ struct FPGA_DataPacket
{
uint8_t reserved[8];
uint64_t counter;

  • uint8_t data[4080];
  • uint8_t data[1008];
    };

struct complex16_t
@@ -20,7 +20,8 @@ struct complex16_t
};

const int samples12InPkt = 1360;
-const int samples16InPkt = 1020;
+const int samples16InPkt = 252;

— a/src/protocols/Streamer.cpp
+++ b/src/protocols/Streamer.cpp
namespace lime
{
@@ -885,7 +887,7 @@ void Streamer::ReceivePacketsLoop()
std::vector<complex16_t*> dest(chCount);
for(uint8_t c=0; c<chCount; ++c)
dest[c] = (chFrames[c].samples);

  •        int samplesCount = FPGA::FPGAPacketPayload2Samples(pktStart, 4080, chCount==2, packed, dest.data());
    
  •    int samplesCount = FPGA::FPGAPacketPayload2Samples(pktStart, 1008, chCount==2, packed, dest.data());
    

I haven’t changed the FX3 part yet but am planning on changing the DMA size too. I hope you find it useful.

Thanks,
Saptarshi