In this series of articles, we will experiment with the definition, implementation, simulation and synthesis of a block of timers in VHDL.
Along the way, we will:
- Test the VHDL code blocks using Vivado simulator.
- Synthesize and implement the VHDL code on Xilinx's Zynq FPGA.
Originally this project was used on a relatively small FPGA. The logic for the timers didn't fit so I used the internal memory to implement the solution. In many of my designs I have seen that it is the LUTs (and not the FFs or the internal RAM) what tends to be under heavy utilization. So using the block RAM to implement register (or timers) banks can be a way to fit a design into a device.
So first, let's start with the code for a single timer component:
- A data_in bus and load signals to load the timer with an initial value.
- An enable signal en to enable the timer down-counting
The width of the timer register is configurable via the generic parameter DATA_W.
Line 35 of the architecture takes care of the loading. If the timer reaches zero (line 40), the done signal is activated. To re-activate the timer after it reaches zero, it must be loaded again.
Let's have a look at the simulation. The first cursor marks the loading of the timer with the value '3'. Once enabled, the timer counts 3..2..1..0 and on the next clock the done signal is asserted.
Another timing cycle is shown following the second cursor marker. During this second timing cycle, the timer is momentarily disabled by de-asserting the en signal. It can be seen that the timer freezes at value six for one clock cycle, then resumes the countdown until done is asserted when the timer reaches the value zero.