4 DAC Oscillator

This is a verilog design targeted at the Xilinx Spartan 3E Starter Kit which uses the rotary encoder and slide switches to control the frequency of a(n) NCO. The NCO phase is used to compute sawtooth, square, triangle and sine waveforms which are output through the 4 DACs.

The user can control the design by twisting the rotary encoder to increment/decrement the frequency byte. Feedback on this adjustment is provided via the 8 LEDs which provide a binary indication of the current value. Additional control is through the slide switches which together form a 4-bit octave value which is used to left-shift the 8-bit value displayed on the LEDs.

The design hierarchy is as follows:

+ analog.v

   + spi_io.v
   |  + spi_txrx.v
   + rotary_decode.v
   + counter_ud.v
   + nco.v
   + tri_gen.v
   + sine_gen.v
      + sc_lut.v
         + sc_lut_init.v

The individual modules are:

  • analog: The top-level of the design and contains the FPGA I/O signals, reset logic, connectivity and some simple code like the square wave logic and sign inversions for the triangle and sine generation.
  • spi_io: Contains the state machine that sequences the four DAC channels onto one SPI bus.
  • spi_txrx: The serial/parallel conversion, clock generation and chip select logic for the SPI bus.
  • rotary_decode: Converts the two phases of the rotary encoder into clock enable and direction for our frequency byte. I borrowed this logic directly from the Xilinx rotary encoder reference design.
  • counter_ud: A simple up/down counter which converts the rotary encoder enable/direction bits to an 8-bit value.
  • nco: A simple numerically controlled oscillator. It is parameterized for 24 bits in this design.
  • tri_gen: Converts the 13 msbs of the NCO phase into a signed (two's complement) triangle waveform by mirroring and inversion.
  • sine_gen: Converts the 12 msbs of the NCO phase into a signed (two's complement) sine waveform. Mirroring is used to compute the address of a 1k x 18 lookup table and inversion is applied for an effective 4k sample waveform. This module computes both sine and cosine simultaneously, although only sine is used in this application.
  • sc_lut: A wrapper for the block RAM which is used for the sine lookup table.
  • sc_lut_init: Not actually a module, this is the initialization code for the block RAM which contains the 1/4-cycle sine data.

Design details:

This design illustrates the basic requirements for driving the SPI DAC, as well as some fundamental types of DSP like the NCO and waveform generation logic. The system runs at a basic clock speed of 50MHz but most operations are controlled by the clock enable of the SPI bus logic which runs at a sample rate of 250kHz.

Because the sample rate is fairly low, the edge jitter found on the sawtooth and square waves is quite pronounced, resulting in noticable aliasing at high pitches.

Design Data

Download the full WebPack design directory here: FourDACOscillator.zip