The worst place to be in digital design is where you load the design onto your device, it doesn’t work, and you don’t know why.

I call this: FPGA Hell.

If you find yourself desk-checking your code and not knowing what to look for, you may be in FPGA Hell. Weeks and months can spent in there, and you will make no progress towards your goal while you are there.

Time is money. FPGA Hell will cost you dearly. Avoid FPGA Hell at all cost.

The solution

The strategy to get out of FPGA Hell is fairly straightforward.

  1. First, simulate everything. If you don’t have a simulation to describe the hardware you are working with, make one.

    As an example, here is a simulation of a UART port. It turns a UART port into either your standard input and output FILE streams, or into a TCP/IP port that you can stream your data in and out of. I built the simulation from an online description of how a UART works. I then use the simulation to debug any Verilog code someone posts to Digilent’s forums, but now that you know my secrets, you can do it too.

    The problem with this first step is: what happens if your understanding of the device you just built a simulator for doesn’t match reality? For that, you need a scope. Specifically, you need to measure reality and learn what’s actually happening, and then you need to adjust your simulation to match reality. This leads us to the second part of the solution: using a scope.

  2. Use a scope. Measure what’s really going on. Watch your code interact with the real hardware, and use what you learn to find where reality and your simulation disconnect.

    A good example of this is my first attempt to build an I2C controller. For that project, I built two controllers, one a slave and the other a master. I then built simulations for both the slave and the master, and then worked with the simulations until my code worked. Once my code worked, I placed it onto the device and … my code didn’t work.

    To get past the problem, I placed a scope into my design, allowing me to “see” what was going on. What I learned was that the hardware I was talking to (my monitor) wasn’t doing what I thought it should. I then had to find a better description of how an I2C port works, rebuild my simulation, get the simulation working again, and then test on the hardware.

    You can find a discussion of the result, together with pictures of what I was looking at, here.

  3. If you cannot use a scope, modify blinky to get the information you need.

Hopefully this helps you avoid FPGA Hell. If not, watch this space. I intend to write more articles here about how to debug an FPGA design and avoid FPGA Hell.