Implementing a Synthesizer in an FPGA

People always tell me that if you’re already a software engineer then FPGA programming is especially difficult. This because of the programming paradigm you are used to. I’m not sure about that myself. The level of abstraction is normally what makes stuff complicated. And of course you will need knowledge of hardware, because ultimately that is what you are interfacing with / building with an fpga (and only plays a minor role in normal software development).

In my day to day job I write software in Scala, which makes parallelizing code easy because it is build into the language and it follows the philosophy that threading etc is best left to the compiler (because that is what humans often mess up). I fear however that that will not translate well to fpga code.


Whoops, yeah - mistyped there!

1 Like

I don’t buy the idea that software engineering is a disadvantage. That we’re often limited to time domain by modern low level programming systems doesn’t mean we can’t design in more abstract terms. Much of modern functional design is intensely parallel and essentially timeless. It’s just that our software is so mind-bogglingly complex that there has to be a sequential element in order to reduce the combinatorial costs. This way I get to represent an infinite series in Lisp by taking advantage of clever programming tricks and thus avoid writing data an infinite number of times on every particle in the known universe.


Its all hard, but its also all fun. I think thats one reason we are drawn to it. :slight_smile:

If we wanted easy, we wouldnt DIY, we would jusy BUY. If we didnt want to innovate, we would emulate.


Today’s update : first sounds!

It’s been a long day, I don’t know how Sam does it and manages to publish so many long videos in such quick succession. I’ll get back to answering comments tomorrow.


Discourse doesn’t like it when we post several times in a row, so I’ll answer several comments in one (long - sorry ) post.

When I used to work for Altera, we sold or gave away our IP blocks in encrypted form, which protected our intellectual property from peering eyes, but occasionally we would sell, for a large amount, a clear text license to a large customer who insisted.

Then, when they hit a bug in a project that included the said IP block, they would start doubting everything about it, every trick only an Altera employee would know about and use, etc, and asking a bunch of questions, looking for bugs in our piece of IP that had already been used and proven in hardware in may projects by many other customers instead of looking in they’re own code where the bug most likely was.

A second source of wild goose chases, is when someone modifies the provided source code and starts getting problems, asks for help without saying they made changes, has support chasing after the problem for ages until something that just cannot happen with the original code is observed and the cat is let out of the bag.

Interesting, I didn’t know that (obviously).
It’s still ( just :slight_smile: ) software though, I don’t know why, but the open source mentality is slower at penetrating the hardware mindset.

I totally understand that point of view, and appreciate the community’s contributions and will try to do my part.

I am not quite ready to publish my “secret sauce”, but I will try to release a simple, but not completely trivial, example or two, to help people get started with FPGAs. But don’t hold your breath, I want to get this project going and have many ideas I want to try out before I can get around to creating (or extracting) something I am willing to share.

Just this morning, while still lying in bed, I had this idea for a cleaver implementation of what I thought was a cool little addition to the oscillator that should be quick and easy to do : a control to continuously vary the output waveform from one shape to another.

It took me the better part of the day to get it working properly and it ended up consuming 5% of the whole device I am currently working with, and that is per pair or waveforms, so you would need three to got from sawtooth to triangle to square to sawtooth. Multiply that by three, as I plan to have three oscillators in the synth voice, and you’ve burned 45% of the FPGA resources just for a less that stellar feature.

That’s one thing when doing hardware design, you always have to be cognizant of the resources that you are using. The FPGA I’m using for this project only has 15 hardware multipliers, so I didn’t want to waste two for that feature, and I chose to implement it in gates, and it cost %5 of the devices gates + one block memory which I didn’t expect (the synthesis engine (AKA compiler) sometimes does surprising things).

Oh well, I had to try it.

Yeah, neither do I, the more experience you have in logical reasoning, task planing, problem solving, design, etc the better off you are to do any kind of engineering.

Some software programming languages are more different from each other than C is from Verilog, or Ada from VHDL and require more different thinking e.g. Java vs Prolog vs Lisp vs Forth vs APL vs assembly vs Brainfuck vs OpenCL etc (and I don’t even know about the more recent exotic languages).


Mini update on Instagram


While sharing is nice, dont feel like you have to.

1 Like

Am I a talking too much? :slight_smile:


Another mini update on Instagram: from “white” noise to S&H to “tunable noise™”

Things like this are to be expected and people will not likely look at their own work to find the problem. But in your case there was a professional relation between Altera and the receiving party which Altera felt it had to keep a healthy one. In the open source world when private people donate something, there it is easier to take the position “Take it or leave it. If it does not work for you or you don’t get it to work because of your skill set, that’s too bad.”

What do you use for DA-conversion in this particular example?

So far it’s been the same cheap S/PDIF to analog converter from EasyDay.
I’m not sure if it’s this one, but it looks exactly like it.

EDIT: I would not recommend it, it seems to have a bad low frequency response and doesn’t handle the Most Significant Bit properly, so you have to keep the range at 23-bits instead of 24 and lose half the dynamic range. (But they are a dime a dozen, so there is that.)

1 Like

Today’s update video.

This is what I used as a tripod. :rofl: :joy:


And you found a way to shorten the outro even more!


I was reminded of this just now…because I just ran into a similar issue - as the client - and the problem 100% was on the vendors side. And even with copious documentation proving it was on their side I had to waste several days repeating myself to their support before they even considered that was remotely possible…then several more days getting them to confirm…and then waiting several months for them to fix it.

If you have good “intuition” you can probably figure out the large corporation who’s well known for their “fast publication” software used by many businesses to manage their finances. Or maybe their “boosted” tax software. In this case trying to submit an invoice to their sytem was resulting in a “Business Validation” error due to the tax calculation on the order. Their support repeatedly tried to convince me that my request was missing a tax amount…even though I had sent them logs of the request showing the tax amount was correctly included. After several go-arounds they finally conceded that yes I was sending proper information so it must be a misconfiguration in the customers setup. But after repeatedly checking they finally admitted that wasn’t the case and agreed to escalate the issue.

After nearly a week of fighting with them it turned out that a rather decently sized city (population just over 10k) in Texas where the customer placing the order lived didn’t exist in their database which was messing with their tax confirmations.

I was reminded of this today because apparently it happened twice more last week with cities in CA triggering it this time.

Frankly it scares the heck out of me how many businesses and individuals trust their financial information to this company given the crazy things I’ve seen working with their API’s and dealing with their support!

I’m not saying the end user is always right. I’ve been wrong plenty. But it’s never good for either side to just assume the problem couldn’t possibly be on their side :smiley:

1 Like

I’ve been working on the Envelope Generator, re-using part of the low pass filter circuit, I found a bug in the low pass filter:

And fixed it:

I got some nicely exponential ADSR envelopes for relatively fast attack, decay and release rates:

(Gate is in green.)

Added a programmable initial delay feature so now I have a dADSR ( delay, Attack, Decay, Sustain, Release) envelope generator (gate in green)

What happens when the gate goes away before the end of the initial delay?
Well at first, it did a full attack phase, but went strait to release, no decay phase. (Gate still in green.)

But that may not always be what you want so I added individual controls to optionally force full attack and/or full decay phases, and another control to decide whether to restart from zero or continue where it currently is when a new gate arrives before the current envelope has completed.
(Too many combinations to show here, this post is already ridiculously long.)

But then I hit a real problem: for (very) long slow envelopes, things turned linear.
(Notice the time scale: 5 seconds per division.)
And yes the gate is in green but too short to see at this scale, (I wasn’t going to hold the button for a full minute.)

The blip at the beginning are normal attack & decay phases.
Linear is bad for long releases, an exponential decay sounds much more natural.

I spent some time on it, increasing the resolution of this and that, and got long exponential releases:

And long exponential attacks:

And long exponential decays:

All together now. (10 seconds per division)

If the Synthesizer on an FPGA never sees the light of day, at least I’ll have made some pretty & cool pictures.

Speaking of which:
The envelope looks off center when the waveform is a narrow pulse

Restart before the end of the previous one.

With a noise waveform

But when working on getting the long slow envelopes to be exponential, I got distracted and didn’t fully test the other features that I had added (force full attack phase and force full decay phase).
I didn’t notice that I had involuntarily added an auto-repeat “feature” because I never held the gate asserted long enough for it to occur.

So my next task is to make auto-restart an optional feature and make the restart happen after the full envelope has completed, not after the decay phase as it currently does.
At least I know that the optional restart-from-zero feature works.

Did anyone actually read all the way to here?

EDIT: typo


I read the whole thing eagerly. Thanks for the great read.


Yeah, I also read it all. It’s thrilling to see this in development!


This is very, very interesting, BUT first I have to understand all the analog stuff :slight_smile: