So we are implementing inverse calculation of 8*8 matrices using LU decomposition on a Basys 3 Artix 7 FPGA:


1) Upon synthesis and implementation, we found that the LUT consumption and I/O cons is extremely high and exceeds by a huge margin. The values are tabulated below:

Consumption       Number Available in the Basys3 board
LUT    173897     20800
IO        931     106
DSP        90     90
FlipFlop 3743     41600

How do I go about optimizing the number of LUTs and IO consumed?


We use an 8 bit representation for each element of the matrix and the code uses a lot of temporary variables inside for statements to get the intermediate results.

The modules are as follows: In the top module, we compute the LU decomposition of the input matrix and then pass the L and the U matrices to the module that computes the inverse. We then pass the resulting values to the output port.

2) We are wondering on how to pass the matrix as an input to the FPGA.

We considered two options:

a)Serializing the input completely (stream the bits via a UART connection from the computer) and developing an appropriate decoding circuitry to assign the inputs accordingly at run time. We are apprehensive about the hardware consumption as we have already exceeded the limits for consumption.

b)Inputting the values in the computer and storing the input in the RAM and reading the values from the RAM and feeding it to our program. We referred to the following link: https://stackoverflow.com/questions/27211466/storing-array-in-fpga , but the answer was not very clear on how to go about each of the method step by step. (Like how to create a GUI (if needed) to pass the input values and then passing it to the board and storing it in a RAM and reading from the RAM) and how to incorporate the code (for reading or writing to RAM) into a source code (if required). I also referred a bit to this manual: https://www.xilinx.com/support/documentation/sw_manuals/xilinx13_2/data2mem.pdf , but being a complete novice, I am not sure on how to proceed.

Please provide a step by step procedure on how we pass and store the matrix as an input and read from it and store the results in an output, any links to relevant IPs which can be included in the code and any extra references which we can learn from.


  • 1
    \$\begingroup\$ We'll need to see your code to help you... \$\endgroup\$ – ThreePhaseEel Nov 25 '17 at 20:14
  • \$\begingroup\$ These are two completely different questions. Please separate them into two EE questions. Otherwise they cannot be properly answered. \$\endgroup\$ – Codo Nov 25 '17 at 20:21
  • 1
    \$\begingroup\$ The best approach for optimization of functional units is to apply your intelligence to the LU decomposition algorithm so that it is well-adapted to the target FPGA cells and interconnects. There is nothing you can do that would be anywhere close to more productive than this. Automatic optimizing compilers are still STUPID and cannot compete with your brain. So apply it. That's recommendation #1. Once you've done your best here, and can demonstrate how you've applied yourself to matching the LU decomp with the FPGA arch, then and only then ask for help with optimizing further. \$\endgroup\$ – jonk Nov 25 '17 at 20:39
  • \$\begingroup\$ Another way of doing the matrix inverse would be to do it in steps and reuse the same module several times. Cramer's rule could work, not efficiently but it would work. \$\endgroup\$ – Harry Svensson Nov 25 '17 at 21:11
  • \$\begingroup\$ I ran the synthesis for each of the modules separately before I integrated them. I shall post the code for the inversion module: pastebin.com/cu3qM1MR Kindly suggest ways to optimize \$\endgroup\$ – thegreatcoder Nov 26 '17 at 21:19

I suspect you have several problems, but my crystal ball is in for service at the moment so seeing the code is a bit tricky. What does the data_mat type look like?

I think you probably have inputs and outputs defined as 8 bits times 64 matrix elements = 512 pins or so, clearly not going to work.

What would probably work would be to declare a 64*8 block ram and then load it using an 8 bit data bus and a 6 bit address select bus plus a strobe, that way you can get the data in over multiple clocks one value at a time using just 15 pins.

Now on to the logic: The usual tradeoff in an FPGA is space for latency, and I suspect from that huge mess of logic that you are trying to get a result in one massively slow clock cycle, I also see division operations in there which turn into a whole mess of logic.

You seem to be writing VHDL like it was software, this is always a mistake, you should be describing a logic circuit not trying to write a program, a fundamentally different way of thinking.

I would have a state machine do one step of each of the outer two loops per clock with a 'trigger' and a 'done' signal pair to control the thing, similarly the division could be a mixture of lookup tables and shift operations that may or may not complete in a single cycle depending on how you trade this off, maybe you could pipeline it.

What are your targets for thruput and latency?

| improve this answer | |

Not the answer you're looking for? Browse other questions tagged or ask your own question.