In FPGA, we use the counter to generate the pulse. What would happen if instead of using a 25 bit counter we used an 8 bit counter? The LED would blink at 50MHz / 2^8 = 195,313 Hz or 195,313 times per second. There is no way our eyes are fast enough to see it blink that fast. Since we can’t see it blink what would it look like? It would not look like a whole lot, it would just appear to always be on! However, the interesting part is that since it is only on for half of the time our eye averages the light and the LED appears to be dimmer than if it was on the entire time!
I recommend you try modifying the code form that tutorial to have one LED blinking from an 8 bit counter and another LED always on so you can see the difference.
How does PWM play into all of this? As you may have guessed, by varying the duty cycle of the signal we can effectively control the brightness of the LED! With a 0% duty cycle the LED is off, with a 100% duty cycle the LED is full brightness, and by controlling the duty cycles we can reach any point in between.
When we were blinking the LED we used a simplification because we always wanted a 50% duty cycle. Instead of saying the LED should be on when the counter is greater than half its max value, we simply used the most significant bit. However, in the case where we want to create a signal with an arbitrary duty cycle we need to be able to control the value we are comparing the counter to.
Here is an example where we want to create the same 33% duty cycle signal shown before.
You can see that by simply raising the value of Compare to 2/3 of Max our duty cycle became 66%!
To implement this in Verilog is pretty simple and only requires a few modifications to the blinker code.
module pwm #(parameter CTR_LEN = 8) (
input [CTR_LEN - 1 : 0] compare,
reg pwm_d, pwm_q;
reg [CTR_LEN - 1: 0] ctr_d, ctr_q;
assign pwm = pwm_q;
always @(*) begin
ctr_d = ctr_q + 1'b1;
if (compare > ctr_q)
pwm_d = 1'b1;
pwm_d = 1'b0;
always @(posedge clk) begin
if (rst) begin
ctr_q <= 1'b0;
end else begin
ctr_q <= ctr_d;
pwm_q <= pwm_d;
Let’s put this all together in a project. Create a new source file called PWM.v and add the contents of the code above.
This code has something new, the parameter. Parameters are constants that are used to configure the behavior of a module when your code is synthesized. These are useful for making generic modules that can be reused.
Parameters are declared before the IO ports by using the #( … ) syntax. You can list as many parameters as you like by separating them with commas. If you assign a parameter a value, like we did in this example, then that is the default value and will be used if a value isn’t specified when the module is instantiated.
Instantiating the module
Just like before, since we added a new module, we need to instantiate it in the general file.
For this example we are going to instantiate 8 PWM modules and give each one a different constant compare value. That way we should get each of the LEDs to be at a different brightness.
// 50MHz clock input
// Input from reset button (active low)
// cclk input from AVR, high when AVR is ready
// Outputs to the 8 onboard LEDs
// AVR SPI connections
// AVR ADC channel select
output [3:0] spi_channel,
// Serial connections
input avr_tx, // AVR Tx => FPGA Rx
output avr_rx, // AVR Rx => FPGA Tx
input avr_rx_busy // AVR Rx buffer full
wire rst = ~rst_n; // make reset active high
// these signals should be high-z when not used
assign spi_miso = 1'bz;
assign avr_rx = 1'bz;
assign spi_channel = 4'bzzzz;
pwm #(.CTR_LEN(3)) pwm_1 (
pwm #(.CTR_LEN(3)) pwm_2 (
pwm #(.CTR_LEN(3)) pwm_3 (
pwm #(.CTR_LEN(3)) pwm_4 (
pwm #(.CTR_LEN(3)) pwm_5 (
pwm #(.CTR_LEN(3)) pwm_6 (
pwm #(.CTR_LEN(3)) pwm_7 (
pwm #(.CTR_LEN(3)) pwm_8 (
For this example we set CTR_LEN to be 3 because we only need 8 different brightness values. For whatever reason, when you instantiate the module the parameters come before the name of the instance.
Go ahead and synthesize the code in ISE and load it onto your Mojo. You should see the top LED is fully on and each one under it is slightly dimmer.