In digital circuit, you can have only either ON state – a full power or OFF state – zero power. However, you can control the power delivered to your components by modulating the amount of time it’s in ON state and the amount of time it’s in OFF state. For example, if you turn on for 1 second and turn off for 1 second. The power is effectively a half of the case where it’s always on (1 out of 2). If we switch an LED on and off so quickly, our eyes wouldn’t see it blinking, but we perceive it as dimmer. The amount of time it’s on relative to the total time of the cycle is called DUTY cycle. This way of making the length of the pulse to contain some information (for example LED brightness) is called Pulse Width Modulation. If you’d like some drawings and graphs, Arduino has an excellent article on PWM here.
With programmable logic, we work at lower level where we have to manipulate individual basic components ourselves. For PWM generation, we’d need 2 simple digital logic components. First we need a timer that runs from 0 to 99 (100 counts representing 100%) and restarts. Second, we need a comparator that checks the timer value. If TIMER < X, then output 1, else output 0. X is now our duty cycle. Yeah, it’s that easy. The Arduino or other micro processors basically use the same mechanism. However, you don’t see it the circuit and you only need to provide the value X.
From that basic circuit, we now build a more difficult one that employs another counter that updates the Duty Cycle automatically. The final effect is that the LED brightness is ramping from OFF to Fully-on state.
If you think the dimming of the LED is still not good. You can try the last example here where the LED is dimmed more gracefully. Off –> getting brighter –> Fully bright —> getting darker –> fully OFF. :
The whole project can be downloaded from here. This project can be easily recompiled to work with another FPGA/CPLD by just updating the Device and Pin-out assignment. So you can run it on any Altera’s device board you have.