Tiny audio synth implemented on TinyFPGA BX


Oh, yeah, that’s a bit closer to what I had in mind … :). Thanks for the pointer! (and thanks Clifford!) :slight_smile:


You have an awful lot of blocking assignments (=) in your code. I suspect a lot of them should be non-blocking assignments (<=). I suspect this is what is causing you to use so many resources, and arachne-pnr to take so long.

Nice tune, though.


I’ve just been looking into it a bit now - it seems like it’s the “flanger” effect that’s taking the lions share of the resources, and that, in turn, seems to be because its delay-line storage is not being inferred as a block RAM (I’m sure there’s a good reason for that, but I don’t know it at this point)…

I’ve just started trying to rewrite the flanger around a SB_RAM256x16 RAM block - ie. from the SiliconBlue library (the dual-port nature makes it ideal - It allows me to have separate read/write pointers), but it seems like yosys is unable to recognise it:

ERROR: Module \SB_RAM256x16' referenced in module\flanger’ in cell `\delay_buffer’ is not part of the design.

After looking at the code here: https://github.com/YosysHQ/yosys/blob/master/techlibs/ice40/cells_sim.v. I wonder whether I need to use a SB_RAM40_4K block instead, and pass in READ_MODE and WRITE_MODE parameters.

Duly noted re: the blocking assignments too. I’m learning more about this as I go, and I’ll probably do an optimisation pass at some point to fix some of the atrocities I’ve been creating.


Yes, I get an explosion of resource usage, when BRAM is not used for memory. At least one case of that was caused by typo where I used a blocking assignment instead of a non-blocking one.

You should not need to use SB_RAM… block. Just put your RAM in a separate module, make sure it uses non-blocking assignments, has inputs for addresses, enable flags and data in, and an output for data out. It sometimes gets turned into registers if one a tiny amount of memory is accessed. It also must only have one write to memory.

There is quite a bit of code that I wrote a few months ago that I need to rewrite. I have been doing this since February when I got my myStorm board.


Hmm… that’s all interesting… I’m sure that I was breaking all of the rules, and I imagine yosys would have had a hell of a time unpicking what I was trying to do.

I’ve just added a commit which uses the SB_RAM block explicitly, and it seems to work okay for me locally… compile times have come way down, and from what I can see it now uses about 4,000 fewer cells, and 4,000 fewer wire-bits… It’s actually very impressive how much stuff you can fit in one of these devices - especially when you don’t abuse the hell out of it :slight_smile:



That version builds much much faster.


You’re right, :grin:
In my tests I use the schemes suggested in appendix A of this document:


I did not have to instantiate the SB_RAM blocks,
yosys infers under this scheme that BRAM must be used. :wink:


Here is my setup for tiny-synth with @gundy’s midi example:


Nice one! I forgot to mention I had that working… it took a little more reading the obscure parts of the MIDI spec than I expected, but the simpleuart code worked an absolute treat!


I am looking at extending your midi example to include the ability to vary the instrument in some way. Do you have ideas on how best to do this?

I was thinking of adding some rotary switches to vary some of the parameters of the voices, such as the waveform, decay, attack and sustain, a bit like a Moog synthesizer. But I saw that you had changed the voice module to one with fixed parameters for the midi example. Am I going to run out of resources if I add variable inputs to the voices?

Another possibility is to implement the patch midi commands and send them from a microprocessor, probably using a second uart. If I did that I might do it on my myStorm board as that has an arm processor and Arduino headers, so I could use the Gameduino 3 as the user interface. But I think I would prefer to try something simpler that I can use to play about with the instrument sound first. (I have the synthesizer running on myStorm).


Before @lukevalenty distracted me with his tile-based graphics ideas (heh, no hard feelings :)), I was thinking about maybe implementing some of the other MIDI commands to control the way things sound. Patch commands are one option, but as another example, my keyboard has a bunch of additional controls (pitch bender control, sliders, …) that can be configured to send MIDI messages, and I thought that it might be a bit more convenient to use those for parameter setting rather than needing to use a PC. I’d started to implement a state-variable filter (HP, LP, BP, NP) with variable cut-off - I thought that might be an easy first thing to try connecting up to a control.

I’m not sure about resources - I think it’s getting a little close at the moment - but that said, I think it’s using 8 voices, and that could be trimmed back to a smaller number if space gets tight.


Also, thanks for the links that you sent through on the github project :).

I’m interested in the PMOD idea that you suggested too - I think I might also build a PMOD module for the MIDI input. My current bread-board setup is a little bit … fragile… especially when put up against adversaries like my cat :smirk_cat:


Some boards such as the myStorm and icoBoard have multiple Pmod connections. The standard was developed by Digilent who make lots of different Pmods, and whose (non-icestorm) boards use them.

Single row Pmods can be plugged into a breadboard and used with the TinyFPGA. There are a few that I plan to try such as the Digilent microphone board. Double row Pmods or double-connector double-row Pmods (like the Digilent VGA Pmod) would need a PCB that you could plug the TinyFPGA into, and which would provide double-row Pmod connectors. I might make one of those. The Digilent VGA Pmod has 4-bits for each color.


I did not have a Midi keyboard, so I bought Rock Band 3 one, as they seem to be by far the cheapest ones that yoiu can get with a Midi out Din connector.

They do seem to have some limited ability to send other midi messages - see http://www.fakebitpolytechnic.com/wp-content/uploads/2013/07/rb3keyboardmidimanualv2.pdf.


I’ve actually just ordered a bunch of stuff from digilent - the VGA PMOD included… I guess the FPGA bug has really taken hold :-).


I tried a version with with the waveform (triangle, sawtooth, pulse, noise) set by switches. It just about had enough PLBs. I ran it on my BlackIce board as that has some built-in switches, but it should work on the TinyFPGA with switches or using breadboard wires a bit like mini patch cables to set pins 16-19 to GND or 3.3v.

It does vary the instrument in interesting ways, but noise is a bit overwhelming, and pulse combined with anything else makes the volume very low.


I now have a midi3 example, which is midi2 plus a rotary encoder for setting the pulse width. I can get a few more different sounds out of it:

Again I tested it on BlackIce with a homemade rotary encoder Pmod, but it should work on the TinyFPGA with the rotary encoder module connected by breadboard wire.

I have ordered some more rotary encoders, so I might make a panel with some switches and rotary encoders on it, in the style of a MiniMoog.


An audio synth board with a TinyFPGA BX socket would be very cool. :sunglasses:


I have now added a midi4 example which has a second rotary dial for sustain. I had to cut the voices down to 6 to fit this in. I pulled your latest changes and incorporated them into midi3 and midi4.



What rotary controls are you using lawrie? I’d love to get some and have a play too.

I started mapping out the rotary controls on my MIDI keyboard today too - it turns out they’re mapped as B0 0E -> B0 15 messages, so I can now start building something to use them too… Today was a bit of a write-off with other things going on (hot-rodding the coffee machine amongst other things), but I’m hoping to get back into it tomorrow. :slight_smile: