Humbled by a sine wave oscillator

The old saw goes, “oscillators don’t, amplifiers do”, but that’s an analog saying.  It doesn’t apply to the digital world.  After all, digital is easy, while analog is hard, right?  (Be careful not to answer too quickly!)

For the last few weeks, I’ve spent my tinkering time on adding sine wave sidetone to the Verilog iambic keyer. As you may recall, sidetone is audio feedback for the keying, in other words, audible Morse code.  My thinking was that while this would appear to be a side trip on the way to FPGA-DSP radio nirvana, it would actually be valuable.  My vision for the radio will require sine wave synthesis in a couple of places.  Also, to have sine wave sidetone, I will need a digital-to-analog converter (DAC), so why not put theory into practice and build a delta-sigma DAC?

I looked around a bit to find a good way to synthesize a sine wave.  I didn’t want to do a simple ROM lookup table, because the radio will need memories for storing filter data and coefficients.  Instead, I settled on an algorithm that uses two integrators and a multiplier.  For some ratios of clock to output frequencies, the multiplication by [latex]-m[/latex] can be reduced to a simple right-shift, which is always appealing to a hardware designer because it can be implemented without any gates.  The negation can then be absorbed into the first adder, costing little more than a set of inverters and a carry input.

Two-integrator sine wave oscillator

Then I found this elegant topology in Delta-Sigma Modulators: Modelling, Design, and Applications, by Bourdopoulos et al:

Digital sine wave oscillator with delta-sigma feedback

In this design, the multiplier has been replaced by a delta-sigma modulator and two constants.  This is gorgeous!  First of all, the multiplier is gone, replaced by a few adders and a mux.  Secondly, the delta-sigma bitstream is a built-in output for a DAC. There are a couple of wrinkles. First of all, there needs to be a scaling by [latex]2^{-b}[/latex] before and [latex]2^b[/latex] after the delta-sigma modulator. Otherwise, the modulator will see signals outside of its stable range. (Stability is a topic for a future tutorial in the How Delta-Sigma Works series.) Second, I’m not sure about putting the delay of the delta-sigma converter into the loop. It seems to me that the two integrators should be non-delaying. Third, are the two integrators sufficient filtering to remove the delta-sigma’s high-frequency noise, or is there a risk of high-frequency feedback making the loop unstable?

It sounds great, but when I coded it up in Verilog I couldn’t get it to be stable.  I fiddled with constants and bit widths for a while and couldn’t get it going. I also tried two non-delaying integrators in the loop. That didn’t work, either, and I couldn’t figure out why. Rather than do any stability analysis or model it in Octave, I decided to cut my losses and go to a more direct approach.

I took the original sine wave oscillator topology, which I easily got working, and tacked on a delta-sigma modulator to the output.  I decided to increase the clock rate in order to get a better signal-to-noise ratio (SNR) out of the DAC.  The oscillator blew up – unstable again!  After some more fiddling, I realized I was going to have to run with 24 or more bits of precision if I stuck to the design in the first figure.  To reduce the precision I needed to carry, I instead split the scaling between both integrators:

Sine wave oscillator followed by delta-sigma DAC

I fiddled with fewer bits, but with the clock-to-output frequency ratio I was working with (1 MHz clock, 800 Hz output), I needed all 16 bits to see a pretty sine wave in the ModelSim waveform viewer.

It looked great in the waveform viewer, so I burned it onto the FPGA and… noise. There is a brief tone buried in the noise, then it turns to all noise, and a little later, to a high-pitched whine without noise. The sine wave buried in the noise might mean I need better filtering between the FPGA and the audio amp (I didn’t use any, relying solely on the audio amp’s rolloff), but the all-noise and whining stages tell me that the oscillator or modulator is unstable. I probably didn’t run the testbench long enough in simulation to see it.

Meanwhile, at work, I’ve been having a great time introducing Test-Driven Development (TDD) into our firmware development process. The process was tedious at first, but now that I’ve been doing it long enough to see the results, I love it!  My code is better organized, better tested, and more solid than ever before.

That, combined with my frustration with the sine wave project, led me to think about applying Agile software engineering techniques to Verilog development.  I did some Google searches to see if anyone else is applying TDD or full Agile to hardware.  They are!  ( Why Agile is a good fit for FPGA and ASIC development)

I learned some technical things while working on the sidetone. More importantly, though, I was reminded that methodical, well-tested development is not only better than seat-of-the-pants hacking, it is faster as well. Hobby projects benefit from discipline just as much as professional ones. I am going to set aside the sidetone project for a while and look at some other things.  Meanwhile I am going to think a bit about how to apply TDD and some other Agile concepts to my humble basement tinkering.

A Morse code keyer in VHDL

I found another FPGA Morse code keyer project! This one is written in VHDL by Jim Brady. He has posted the source (for a Xilinx Spartan 3A).  He also posted his vintage keyer designs from the 1960’s and 1970’s.

Jim’s design is not iambic, but does have dot and dash memory. Speed adjustment is done via an RS-232 serial link to a PC.

If VHDL is your hardware language of choice, or if just would like another take on Morse keying, Jim’s keyer is worth a look.  Of course, if you’re interested in a small iambic keyer core in Verilog, have a look at the iambic keyer.

Update 8/8/11: Jim tipped me off to another VHDL keyer published online. This one is designed for a Cypress CPLD and is written in VHDL. It’s on pages 53-73 of Circuits I Have Known, by Ronald W. Parker. A PDF is available at, and the book itself is available at Amazon.

The iambic keyer core is alive

With just a few tweaks, I brought up the “IambicV” iambic keyer core on one of my A3PN250 breakout boards. I was stunned when it made dits, dahs, and iambic dah-dits perfectly the first time out. Yes, I know that’s what a testbench is supposed to make possible, and yes, I’ve had it happen before, but I still always expect smoke the first time I turn something on.

I made a few changes from last week’s version. One change was to invert the dit and dah pins. Although high-true logic is convenient within the keyer module, it seems like a good idea to have the actual paddles grounded, so the inputs had to be low-true. The physical constraints file enables the built-in pull-up resistors on the dit and dah pins.

For an audio amplifier, I used an old Saint Louis QRP Society LM380 board.

It’s all lashed together on my bench, but it works.

To download the core, see the iambic keyer project page.

Iambic keyer in Verilog

If my goal is to build an FPGA-based ham radio, one of the modules I can’t do without is an iambic keyer. I have to confess that I have never been much of a CW (Morse code) operator, but with so many logic gates available, it would be a shame to leave out a keyer.

The basic idea behind an iambic keyer is to use a two-lever “paddle” to send Morse code. Pressing one paddle, usually with the thumb, sends a series of dits (dots), and pressing the other paddle, usually with the index finger, sends dahs (dashes). Squeezing both paddles alternates between dits and dahs. The didahdidahdidah… sound of squeezing the paddles sounds a bit like the iambic feet of English poetry, hence the name “iambic keyer”. If Shakespeare were a Morse code operator, one of his sonnets might include the sweet iambic pentameter “didahdidahdidah, didah didah!”

Writing an iambic keyer turned out to be a good way to get the kinks out of the FPGA toolchain. The code itself is pretty simple and straightforward. One flip-flop keeps track of whether the current symbol is a dit or a dah. Another tracks whether the paddle for the opposite symbol (dah or dit, respectively) has been pressed during the current symbol. Finally, a two-level counter handles the timing of the dits and dahs and operates the key line. There is a simple sidetone, too. Continue reading Iambic keyer in Verilog