Sinus wave generation with Verilog using Vivado for a FPGA

(Last Updated On: March 13, 2018)

In this article I am going to show how to generate a sinus wave in a FPGA with Verilog and VHDL. I am going to program and demonstrate the functionality with Vivado 2017.4. This is going to be divided into 3 parts:

  • Fixed frequency sinus-signal
  • Variable frequency sinus signal
  • sinusoidal-PWM

Fixed frequency sinus-signal

The first problem is how to store the sinus wave in the memory. Because calculating the sinus is more resources-intensive and complicated than storing hundreds or thousands of values.

Therefore, there are two nice ways (maybe more) to load the memory values at the start.

1- Reading it from a file using the $readmemh command.

2- Giving individual value of each memory register

After creating a new Testbench in Vivado, I wrote the Verilog source file:

In this example I am going to read them from a memory text file. For this add a new source file

The wave sinus values can be generated in a multiple way: the smartest and better one could be with matlab or a python script. The easiest and fastest one is use an online sine generation tool.

Copy them and paste in Vivado

Go to the replace menu window with right-click over the mem file. The “0x” and the comma is going to be removed.

 

 

 

 

 

 

The module only need a clock input to be tested:

In this example the clock is set to 50MHz.:

Each clock cycle corresponds to a sinus step. The resulting frequency is therefore around 50 kHz

Variable frequency sinus signal

The previous wave sine had a fixed frequency, dependant of the input clock. Now we want to give a certain frequency as an input. For that the previous block is modified.

The input “Frequency Control Word” (fcw) is continuously added to the phase accumulator, which corresponds mathematically to integration. This value corresponds to the phase angle x of a sine function sin (x), which is stored in a table, in this case, of 1024 values. The table map one full period. This table is implemented inside the ROM (Read-Only Memory).

The input width of the phase accumulator is 24-bit, and the 10 most significant bits are used as the address for the sine table, so that the phase resolution is 360/1024 = about 0.3 °.

The Verilog implementation:

This can, of course, be in VHDL implemented. In VHDL the sinus table can easily be written inside the code (without reading from a file). I will show this solution in VHDL:

 

PWM output

First a brief PWM theory: The Pulse Width Modulator generates a periodic sequence of pulses whose duration is proportional to the value of an input signal.

A numerator compares the signal value with a sawtooth signal, and as long as the sawtooth signal is greater than the signal value, the output pulse is set active high.

Using an analogue signal as input a PWM (Pulse Width Modulation) signal is generated. For this a comparison is used as shown in the following schema:

comparison of the input signal and the sawtooth

The Verilog Code

For this the VHDL code is:

For this simulation the previous developed block is used as input for the PWM generator block. For that a new 8bits sine wave was generated.

Leave a Reply

Your email address will not be published. Required fields are marked *

Scroll to top