Last week I was made aware of this post on RS DesignSpark about a project, currently in the very early planning stage, to build a Sinclair Spectrum on an FPGA. As it happens I have a similar project well under way, and I have promised to write it up…
Several years ago I implemented most of the ULA in VHDL on a MAX7000 CPLD, mainly as an exercise to brush up on my HDL. I didn’t have enough space to fit the keyboard interface so it was pretty useless, but it did boot! The complete system used a pair of SRAMs, real Z80 and the Sinclair ROM in flash.
Back at the beginning of this year I decided to brush up on my HDL again and I bought myself an Altera DE1 development kit. The heart of this board is a Cyclone II FPGA with a range of support hardware including 512KB SRAM, 8MB SDRAM, 4MB flash, an I2S audio codec, VGA port and the usual switches, LEDs and buttons. I would highly recommend it for anyone looking for a relatively cheap way to play with FPGAs.
This time I decided to put as much as possible into the FPGA. All the core ULA logic is in there along with a Z80 soft-core (T80 from opencores), the ROM, proper bus routing (the real Spectrum used a lot of tricks that simply aren’t an option in an FPGA), VGA scan-doubling for the video output, logic to drive the I2S audio codec, plus a PS/2 keyboard interface. Apart from the audio codec, which is absolute overkill and only used because it is already on the board, the only other key part external to the FPGA is the SRAM. This is used for both contended and non-contended memory regions by a method which I will cover in a later installment.
A full write-up will follow, along with better pictures, video and full VHDL for the project once it has been cleaned up a bit. In the meantime here are a couple of photos of the thing in action (click for bigger, and yes I did load that from a real tape!)
What is that game in the screenshot? I remember playing it but can’t remember the name!
Feud. It was one of those £2 Mastertronic budget games you used to get from the newsagents 🙂
Ah yes! I remember now.
Awesome work! I only managed to learn a little VHDL when I had an electronics class in the University (I graduated in mathematics and then started computer science, but gave up as I found most classes boring or useless…) but I thought it would make for nice projects… Yours is sure one.
Thanks for sharing,
Neeto, check this out http://zet.aluzina.org/index.php/Zet_processor
completed 8086 DOS computer runs win3 on the same DE1 board
great news. Will it be possible to upload some games through the DE1’s sd-card interface? That would be pretty cool.
That is the plan, yes. I intend to implement this by paging hidden ROM and RAM into the Z80’s address space at startup to run custom firmware. More on this in the full write-up.
next step: hardware bus expansion compatibility (for peripherals), rf-out (pal, ntsc), pcb compatibility on original sinclair cases, 8+5 connectors zx-spectrum keyboard compatibility as well (besides ps2), 128k, +2,+3 and +2a compatibility, etc. – but anyway, it’s an awesome progress! 🙂
All good ideas. I’m quite keen on adding support for the 128k and above, especially for the improved sound. Using a real Speccy keyboard would be trivial – the 8+5 signals are already present internally. The PS/2 interface just connects onto them.
Hey Mike where can I download this project?
Hi. The VHDL needs some clean-up first then I’m going to host it either here or on github. I’ll try to make some progress on it over the weekend because I know a few people are waiting for it.
Congratulations! I am very fascinated by this. The big question in my mind is how did you do it? I was trying to make out how it was done from schematic in screenshot but it doesn’t zoom well. Did you draw the original ZX Spectrum schematic diagram as logic gates in Quartus and then this produced VHDL code (sorry if this is a silly question – new to FPGAs/VHDL)?
Hi. I must apologise for not having posted the VHDL yet – it has not been forgotten, but I have been mega-busy with my day job.
It was written from scratch (mostly) straight into VHDL, although there are a few pieces from other open-source projects – notably the Z80 and the bulk of the PS/2 interface. Simply taking the original Spectrum schematic and drawing it into Quartus wasn’t an option because it uses too many asynchronous tricks and shortcuts. Modern FPGAs are too fast for this and a fully synchronous design is desirable to avoid hard to debug timing issues and metastability. There are some other differences as well, which I will talk about in detail when I do a full write up. In particular all the RAM is in a single SRAM chip, so there is only one bus – the real Spectrum has a split bus with the lower 16KB shared with the ULA so that it can generate the display. This implementation uses a multi-phase clock to time-slice accesses between the CPU and display logic. A side-effect of this is that all of RAM is uncontended, so this runs faster than a real Spectrum at the same CPU clock speed. Timing accuracy is important for a lot of games and I intend to add some logic to emulate contention in due course.
did you use the Audio Codec from DE1 Board for tape in ?
If yes, how did you initialize it ?
Yes. The register settings are hard-coded in a block of logic that generates the required I2C transactions to load them into the codec. It’s just a state machine that runs on reset and then remains idle.
Would you copy and paste a short code snippet about used registers ? I made a port from zxgate spectrum to my DE1 Board. Audio out works but audio in doesn´t.
Thanks in advance.
–Mike– Thank you for explaining how you implemented the ZX Spectrum. Look forward to looking at VHDL code when it’s ready.
–Dirk– You mention zxgate. All the links to download readme.txt and vhdl code on zxgate.sourceforge.net are down. Do you have a copy of these you can send or upload somewhere?
I hope Mike agreed to this link.
–Dirk– That works, thank you!
Here are the values I use for the codec registers (in address/value pairs).
type regs is array(0 to 19) of std_logic_vector(7 downto 0);
constant init_regs : regs := (
— Left line in, 0dB, unmute
— Right line in, 0dB, unmute
— Left headphone out, 0dB
— Right headphone out, 0dB
— Audio path, DAC enabled, Line in, Bypass off, mic unmuted
— Digital path, Unmute, HP filter enabled
— Power down mic, clkout and xtal osc
— Format 16-bit I2S, no bit inversion or phase changes
— Sampling control, 8 kHz USB mode (MCLK = 250fs * 6)
Thank you very much. I´ll try that.
It works. Thanks.
this is amazing project!
do you have any plan to make a PCB board of complete ZX Spectrum system? I don’t have Altera DE1 board, but very interesting in having such a ZX