03-12-2019 10:31 AM
I'm a beginner in Verilog and my lab project is to turn on LED lights on the FPGA board in a sequential manner. I made the typical FSM and conducted a for loop in each state however I tried making a delay in between each LED output. For some reason after synthesis the delay is ignored therefore meaning that if I were to simulate this on the FPGA board all LED lights would output at the same time.
03-12-2019 12:37 PM
03-13-2019 02:26 AM
The FPGA has no concept of time. To do timing accurately, you need some sort of oscillator - which tends to be incompatible with the sort of manufacturing process used on FPGAs. The Xilinx ones do include an internal clock source to be used during configuration, but it's not very accurate at all and it's not really meant to be used for your own code. You can also build an oscillator in the FPGA fabric, but this is both inaccurate and device-dependant (ie two "identical" chips may generate quite different frequencies).
Obviously people do need to do time-dependant calculations on FPGAs, and for that an external clock is fed in. However, the FPGA still has no concept of "time", it just understands "clock edges". You can count clock edges to calculate time (in increments of whatever the clock period is), but you have to implement that manually - you can't just tell the FPGA "wait seven seconds and then do something else".
Related to this, FPGAs don't do sequential "for" loops. If you have a loop, the synthesis tool will unroll that so that all iterations happen simultaneously. This is why you can't have unbounded loops in the design.
I would suggest that you need a redesign of your block as follows:
(1) Add a counter. On every clock cycle, the counter just increments by one. I'd set the top value to something large, like 50,000,000 if you've got a 50MHz clock input.
(2) In the on_lightup state, instead of the "for" loop, just check if the counter is equal to the specified top value. If it is, then reset the counter to zero and turn on one more light. When all lights are on, move to the on_lightdown state.
(3) Exactly the same thing happens in the on_lightdown state.
There are plenty of other ways to implement this, some of them more "elegant" - but I think this represents the smallest change to your existing block.
03-13-2019 01:34 PM
That makes sense considering that the FPGA emitted all LED lights at the same time once the switch was flipped. I understand what you mean by using a counter to increment to a specific value equivalent to the desired time. In general the FPGA board oscillates at 50MHz or 25MHz frequency therefore the time cycle lasts about 40 ns around there. Each incrementation represents a time cycle so I can just divide the time by the amount of cycles to give me the limit to what I need to increment to. In that case, if all lights are to turn on sequentially then I assume that I'll be needing several more states to represent each LED in the case. Considering for loops are now overly redundant in the program I'll use if blocks instead to output each LED.
03-13-2019 01:35 PM
But I also assumed it would be more straightforward to implement the time delay in the program like I did before with #7.
03-13-2019 01:49 PM
Hello esoud@ ,
As observed, the time-delay is for circuit analysis, not silicon configuration.
Think of it this way, the Verilog FPGA design you use could be implemented in an ASIC [Application Specific Integrated Circuit].
In this case, the specified delay would then be rendered as what?
Unfortunately we need to think like digital designers when working with FPGA, not so much as software designers.
03-14-2019 04:53 AM
esoud@ It would be much simpler to implement the delay with "#7" - if the FPGA actually could implement the delay like that. It can't. Those time delays exist purely for simulation purposes, where you want to (for example) create input signals at specific times.
The only way to implement a delay on the chip is to derive it from a clock.