Archive for the ‘FPGA’ Category

Poppin’ Caps

Monday, February 24th, 2014

The FPGA graphics engine (started around the last blog post from 2012) now has screen capture support! Here are a couple action shots from recent synth work:

Poking Around

Anti-aliased scope plotting!

Wobble

 Spectrogram!

You may wonder why the color scheme is so hideously fantastic. That comes from the loving care that went into picking the perfect colors and definitely is not just because this is an early prototype where the color scheme has been ignored…

Cheap FPGA Graphics, First Attempt

Sunday, December 30th, 2012

I need to find a better way to record video. An iPhone camera doesn’t do justice to the 70 frames per second of the screen.

This was a weekend project proof-of-concept for a low budget FPGA GPU. To be fair, it took a couple nights beforehand to get the display configured to recognize an RGB interface. That configuration is handled by a PIC at the moment.

The FPGA design is made of several engines running in parallel:

1) Background grid generator

2) Audio data plotter (including a UART receiver for getting data from a computer)

3) Geometry engines (one per shape)

4) Parallel RGB interface (this drives the LCD)

To keep the memory requirements tiny, there is no frame buffering of any kind for the geometry engines. The RGB interface steps through each pixel on the screen and passes the current coordinate location data to the other engines. Each engine returns a 1 (pixel on) or 0 (pixel off). The last step is a mixing block that defines the color and depth for the output of each engine. For example, the lowest layer is the background grid. Next up is the circle, and so on up to the audio plot. Only the highest illuminated pixel is shown for each location on the screen.

The geometry engines store the size and locations of their shapes in registers, so the only memory usage comes from the audio data drawn on top of everything. Audio data is being generated by Max/MSP and sent over a USB > serial cable. The FPGA double buffers it so that there aren’t any glitches due to synchronization issues.

A major downside to this general approach is that the amount of logic scales proportionally to the number of objects on the screen. If there are going to be 5 circles on the screen, this design needs 5 circle generators. One way to improve that is to use a faster clock in geometry calculations. Then each engine could handle multiple shapes per pixel.

Long-term goals: thick lines, anti-aliasing, sprites, and text rendering.

Tech details

The display is 320 * 240 pixels running at 70 fps. The complete design as shown uses 415 logic elements, 8192 bits of memory, and three 9-bit multipliers (for circle calculations). For a reference, the smallest Altera Cyclone IV FPGA has 6272 logic elements, 270 kbit of memory, and thirty 9-bit multipliers.

Hurdles

Sunday, July 29th, 2012

The 2nd version Atari synth prototypes came back from assembly early this week, but something has them bricked.
The worst case is that there might be hardware damage (soldering too hot, static zap during handling, moisture problems), since that leaves little I can prove in a post-mortem. At $500 a run, prototypes are not cheap.

<geek notes>
The power supplies measure fine, and JTAG diagnostic tests on the FPGA pass with flying colors. The configuration pins all check out, too. Yet somehow the FPGA will not run. It is not simply a code issue, because the part won’t even run factory code from the manufacturer.
The 2.5V I/O banks appear to be driving out 0.45V intermittently, which can’t be a good sign of anything.
</geek notes>

So that is unfortunate.

To get back to something that *is* working, the 2A03 synth is coming along. It currently has voltage control of:
Pulse wave 1 pitch
Pulse wave 1 volume
Pulse wave 2 pitch
Pulse wave 2 volume
Triangle wave pitch
Noise wave volume

…and knob controls for:
Pulse wave 1 pitch
Pulse wave 1 volume
Pulse wave 1 duty cycle
Pulse wave 2 pitch
Pulse wave 2 volume
Pulse wave 2 duty cycle
Triangle wave pitch
Noise wave pitch
Noise wave volume

Click here for audio of one pulse wave modulated by a couple envelope generators

One of the downsides to using the actual NES CPU is that it has unobvious quirks. It would be far easier to make an FPGA clone of the 2A03 audio engine and just fix the quirks, but what’s the challenge in that?

The pulse wave pitch control registers are a good example. They are 11 bits wide, which isn’t anything special. On the other hand, any write command to the greatest 3 bits will cause a phase reset in the output waveform. In a videogame soundtrack where each note starts with a volume of 0, it might never be a problem. In a synthesizer where oscillators are “on” constantly, it leads to clicking as pitch changes.

I am experimenting with workarounds. One trick is to use the pitch sweep hardware built into the part to trigger an increase or decrease in the upper 3 bits without issuing a write command. That has two downsides:
1) Worst case, it takes almost 20 times longer than just letting the click happen
2) It is more difficult to keep stable

It takes so much longer because it involves writing several non-pitch registers multiple times. That ends up lowering the sample rate on pitch control voltage. The stability issue is just that I see the pulse wave pitch occasionally lock up and refuse to change for several seconds. It is probably due to some corner case I have not found yet, but it never happens in the clicky version.

I cannot take credit for the clever idea to use the sweep unit, by the way. That came from the nesdev.parodius.com forum.

I made a demo to show the difference. The following audio file alternates clicky/smooth/clicky/smooth through some pitch modulation.

Click here for audio

Early Tests of Max/MSP Controlling 2A03 (NES CPU) Audio

Monday, December 12th, 2011

My last post mentioned that I had an interface working for controlling the 2A03 at a reasonably fast rate. Last week I wrote a serial data receiver (UART in this case) into the 2A03 control logic so I could send the 2A03 commands from Max/MSP. I technically could’ve used MIDI, but at 31,250 bps it is far too slow for all the data I want to send as quickly as I want to send it. I opted for 1,000,000 bps with the option to speed it up further later.

The chain looks like this:
Max/MSP -> FTDI USB-to-UART cable -> FPGA development board -> 2A03 adapter

It works just as well as I hoped. I basically have real-time control over all the NES audio registers from Max/MSP. Here’s a screenshot of the big ol’ mess in Max:

It serves as a quick idea prototyping/test platform for the NES synth module, so it changes too frequently to bother making it tidy.

This post is boring without audio, so how about a few test recordings? These are all straight from an NES CPU into the preamps on my sound card.

Click here for clip 1 – triangle wave FM

The pitch of the triangle wave is modulated by a sine wave in Max/MSP. There is a lot of jitter in the timing not only because of the serial transmission, but also because I have to convert the sine from an audio thread in Max to control data to use with the “serial” object. Control data timing is not designed for audio. It worked decently given the circumstances.

Click here for clip 2 – pulse wave delay

One of my favorite Nintendo sounds is two pulse waves configured as an echo effect. I am just playing with a few settings (delay time, second wave volume and duty cycle). The percussive nature of the voices comes from an envelope with an attack time of zero and a short decay to silence. The envelope and all other data is being completely handled by Max and dumped out over USB. The pops in the audio are from a known control issue. They will get better and go away as I tweak the control logic.

Click here for clip 3 – noise bursts

I couldn’t post audio tests without including the noise channel. This is a steady stream of short bursts (zero attack time and fast release time) with pitch and timbre being adjusted by hand then linked to the amplitude envelope in fun ways.

SID Oscillator Verilog Fun

Monday, April 12th, 2010

The past few days I’ve been waiting for Pokey synth front panel circuit boards to come in, so I thought I’d play around with some “soundchip” Verilog. Kevtris has already done a SID emulation in an FPGA (and understands the internals of the SID far better than I do), but I haven’t seen any code posted. I saw this blog post and eventually ended up at this interview I bookmarked a year or so ago.

I wrote some Verilog strictly according to the interview, specifically making an oscillator with triangle, saw, pulse, and noise outputs. I added in the logic “AND” of the triangle and saw waves as an additional waveform, according to Bob Yannes’ comments about multiple waveforms being selected at once. Here’s what the digital outputs looks like:

Only the Waviest

Only the Waviest

My source code is available here. I included excerpts from the interview as comments because it just felt so right. Open it with Notepad++ for best results (if you want all the formatting to line up properly).

What I still need to figure out:

The interview mentions that the LFSR for noise generation is clocked by one of the accumulator bits. Which bit is it?

Another excerpt from the interview that I’m partially unclear about: “The combination was actually a logical ANDing of the bits of each waveform, which produced unpredictable results, so I didn’t encourage this, especially since it could lock up the pseudo-random sequence generator by filling it with zeroes.” A linear feedback shift register shouldn’t be able to get filled with all zeros on its own. This implies that the LFSR shift register does not take feedback taps from itself, but actually taps somewhere further down the line (after the logical AND). Is it actually feeding back from the Waveform D/A input bits? In that case, what happens to the LFSR while it isn’t selected as a waveform?

Are the inputs to the Waveform D/A registered synchronously to the master clock, or do glitches pop up from not having every bit change at exactly the same time?

At this point I really need to fire up an actual SID to start checking my assumptions, but I’m afraid that if I touch a SID now then I’ll end up too distracted when the Pokey synth prototype PCBs come in.

1-bit FPGA D/A Update

Monday, February 8th, 2010

Most of my hobby time lately has been spent sourcing parts and doing circuit layout for the Pokey module, but yesterday I spent a little more time with the 1-bit D/A I was working on. Spectral plots are in order!

Running the output of the FPGA directly into my soundcard with a couple wires, this is the output spectrum for a 1k sine wave:

Blue Picket Fences

Blue Picket Fences

Alright, so that looks pretty terrible. The sine wave data is 16-bit, so the noise floor should be around -96 dB (the bottom line of the graph), yet it’s in the -86 range. There’s also a lot of distortion: both even and odd harmonics.

One potential reason for these problems is that my soundcard probably does not like 25 MHz input frequencies. To help that a little bit, I added an RC filter between the FPGA and soundcard. Using 16 kHz as a cutoff, the new result looks like this:

Noise Censorship

Noise Censorship

That’s much better. True CD quality would just have one spike at 1000 (for 1 kHz), as 2k, 3k, 4k… are distortions. The worst case offender is just under -40dB, giving this converter noise performance greater than 16-bit, but distortion performance that’s around 7-bit. I do not have an obvious solution for the distortion problem, nor can I prove with my current setup that it *isn’t* just a result of my soundcard not being able to handle the high frequency energy. If anyone has any insights, please add a comment or two.