Spin FV-1 Emulator
A software emulator for the Spin Semiconductor FV-1 audio DSP.
Abstract
This project is an attempt to develop a software emulator for the Spin Semiconductor FV-1 audio DSP commonly found in guitar pedals and all sorts of digital audio effects hardware. The goal is to emulate the actual FV-1 processor and its instruction set rather than just make another DSP effects library that happens to run FV-1 style effects.
The idea is to eventually be able to take programs written for an actual FV-1, load them into the emulator and run them against either audio files or realtime audio on a PC. This would make it possible to develop, test, debug, and experiment with FV-1 programs without having to constantly program an EEPROM and move back and forth to physical hardware.
Eventually I would also like the emulator to be useful as a debugging and development tool where the internal state of the FV-1 can be inspected while a program is running.
Overview
The FV-1 is a pretty interesting DSP because its architecture is specifically designed around audio effects rather than being a general purpose DSP or microcontroller. The instruction set is relatively small but the instructions themselves can accomplish quite a bit of work.
The FV-1 operates using 24-bit linear audio data and executes 128 instruction cycles for every audio sample. At the normal 48KHz sample rate this works out to about 6 million instructions per second.
The chip has an integrated stereo ADC and DAC, 32 general purpose registers, 32K words of delay memory, three potentiometer inputs, two SIN/COS LFOs, two ramp LFOs, and the DSP core itself.
A program can therefore access audio from the ADCs, process it using the accumulator and registers, read and write delay memory, use the LFOs for modulation, read POT0-POT2 for parameters, and finally send the processed audio to the DAC outputs.
The basic idea of the emulator is to reproduce all of this in software.
At a very high level the process looks something like:
Audio Input -> ADC Registers -> FV-1 Program -> DAC Registers -> Audio Output
For each sample the emulator loads the input audio into the ADC registers, begins executing the FV-1 program, executes the 128 instruction slots, updates the appropriate internal state and delay memory, then collects whatever was written to DACL and DACR as the output sample.
Then it does the whole thing again for the next sample.
Simple enough in theory!!!!!
The fun part is making all of the little details behave like the actual chip.
FV-1 Instruction Set
The first major part of the project is emulating the FV-1 instruction set.
The FV-1 has instructions for working with registers, delay memory, the accumulator, LFOs, branching, filtering, logarithmic/exponential operations, and some other DSP specific operations.
Some examples are:
- RDAX / WRAX
- RDFX
- WRLX / WRHX
- MULX
- RDA / WRA / WRAP
- RMPA
- SOF
- LOG / EXP
- SKP
- WLDS / WLDR
- JAM
- CHO
One thing that makes the architecture interesting is that some of these instructions aren't really equivalent to one normal CPU instruction. A single FV-1 instruction can perform several operations at once.
For example an instruction reading delay memory can read the value, multiply it by a coefficient, add it to the accumulator and update other processor state as part of the same instruction.
So the goal isn't just to parse SpinASM instructions, the goal is to reproduce what those instructions actually cause the FV-1 hardware to do.
Registers and ACC
At the center of most FV-1 programs is the accumulator or ACC.
Most operations either load something into ACC, operate on ACC, or use ACC as part of another calculation. There are also some additional internal states such as PACC and LR that need to behave correctly since FV-1 instructions make use of them.
The processor also contains 32 general purpose 24-bit registers along with special registers representing things like:
- ADCL
- ADCR
- DACL
- DACR
- POT0
- POT1
- POT2
- LFO control registers
Part of the emulator will essentially be a software representation of this entire register bank.
Numeric behavior is also important here. The actual FV-1 isn't using normal PC floating point numbers for all of its calculations, so just converting everything to float and calling it done probably isn't going to produce an accurate emulator.
Especially once feedback, filters, reverbs, and long delay structures get involved small differences can keep accumulating.
The goal is to reproduce the actual fixed point, saturation, coefficient, and rounding behavior as closely as possible.
Delay Memory
One of the most important parts of the FV-1 is the delay memory.
The chip has 32K words of dedicated delay RAM. This memory is obviously useful for delays but FV-1 programs use it for all sorts of effects including reverb, chorus, flange, pitch shifting, comb filters, all-pass filters, etc.
The delay RAM also doesn't operate exactly like the normal 24-bit register bank. It uses its own floating point storage format and its addressing is built around the continuously advancing audio sample counter.
So this part of the emulator needs to reproduce both the memory format and the somewhat unique way the FV-1 addresses that memory.
This is also where things start getting more interesting once the LFOs get involved.
LFOs and CHO
The FV-1 has dedicated LFO hardware running in parallel with the main DSP.
There are two SIN/COS LFOs and two RAMP LFOs that can be configured and then left running while the main program executes.
These LFOs are used heavily for modulation effects, particularly chorus, flange, vibrato, pitch shifting and modulated delays/reverbs.
The CHO instruction ties a lot of this together.
CHO can use the LFO output for delay memory addressing as well as fractional interpolation between delay samples. So instead of a FV-1 program having to manually calculate a moving delay pointer and all the interpolation math, a lot of that functionality is built directly into the processor.
This also makes CHO one of the more complicated parts of the processor to emulate correctly.
Getting CHO and the LFO behavior right will probably be one of the bigger milestones for this project.
POT0, POT1, POT2
The FV-1 has three potentiometer inputs that can be accessed directly by programs.
In a guitar pedal these are generally the knobs controlling whatever parameters the effect designer decided on, delay time, feedback, modulation depth, reverb decay, etc.
For the emulator these can just become software controlled values.
Eventually I'd like to have GUI controls representing POT0, POT1, and POT2 so programs can be manipulated while they are running exactly like turning the controls on an actual pedal.
Program Loading
Another major goal is compatibility with programs intended for real FV-1 hardware.
The FV-1 can run eight programs from its internal ROM and another eight programs from an external EEPROM. Each program consists of 128 32-bit instruction locations.
Initially the emulator will be focused on executing the assembled instruction data itself.
Eventually the idea is to have a workflow something like:
SpinASM -> Assembler -> FV-1 Program Binary -> Emulator
This means existing FV-1 programs could potentially be loaded into the emulator without modifying the actual DSP program.
I'd also like to eventually support loading complete EEPROM images containing all eight external programs and selecting between them just like the program selector on the actual hardware.
Why?
Mostly because I have been interested in audio DSP for a long time and the FV-1 is a really interesting piece of hardware.
There are plenty of tools for writing and assembling FV-1 programs but testing usually eventually comes back to actual hardware. Change the program, assemble it, program the EEPROM or development board, play some audio through it, listen, change something and repeat.
That works but I think there is a lot of room for better development tools.
Being able to execute the same program entirely in software creates some interesting possibilities beyond just listening to the output.
Registers could be inspected.
ACC could be watched while instructions execute.
Delay memory could be visualized.
LFO output could be plotted.
Programs could be single stepped.
Audio could be run through the emulator faster or slower than realtime for testing.
The results from the emulator could also be compared directly against recordings or test signals processed by an actual FV-1.
In short the emulator itself is only part of the idea, I would eventually like to build an entire FV-1 software development/debugging environment around it.
Project Goals
The project will be developed in stages. First getting the basic processor and instruction decoder working, then progressively adding the more complicated pieces until complete FV-1 programs can run.
Current overall goals are:
- FV-1 instruction decoder
- ACC/PACC/LR behavior
- 32 general purpose registers
- ADC and DAC register emulation
- POT0, POT1, and POT2
- 24-bit DSP arithmetic
- Coefficient decoding
- Saturation and rounding behavior
- 32K delay memory
- Delay memory addressing
- SIN/COS LFOs
- RAMP LFOs
- CHO instructions
- SKP/program control behavior
- LOG and EXP instructions
- FV-1 binary/program loading
- WAV file input/output
- Realtime audio
- Virtual POT controls
- Internal processor state/debugging tools
- Testing against known FV-1 programs
- Testing against an actual FV-1
The ultimate goal is for the software to behave closely enough to the real hardware that an FV-1 program doesn't know or care whether it is running on the actual chip or inside the emulator.
Lots of work to do but that's the fun part!
AVR