Wednesday, 9 July 2014

Improving simulation of the C65GS to help with debugging

I am continuing to slog through reimplementing much of the CPU and VIC-IV to reduce the size, and hopefully improve the CPU speed.

One of the great pains with VHDL is the time it takes to synthesise (that's VHDL/FPGA speak for "compile") a design.  In the case of the C65GS it varies between 10 minutes and an hour.

Even then, when you spot something wrong, it can be quite hard to work out what it is so that you can start fixing it.

This is why there are simulation tools that let you run VHDL code, albeit really slowly.

However, it isn't quite that simple in practice, especially if you are using the open-source GHDL VHDL simulation tool.

A lot of the problem comes from the Xilinx core generator that is the recommended way to create large memories and other useful stuff in an FPGA design.  Those cores are specified in a very hardware-specific manner.  They do include simulatable versions, but none of them run in GHDL.

A while back I had already started making my own simple memory modules in VHDL.  The only ones that were too tricky to get right so that the Xilinx tools knew what I meant was true dual-port memory where two different things can read and write at the same time.  This meant that I couldn't simulate chipram, which really scuttled any sensible simulation.

However now I have changed the design so that chipram is only ever written to by the CPU.  Reads from chipram are serviced from a separate shadow ram.  This means that chipram is fastram on the C65GS, but more importantly, it removed the barrier to simulation.

So over the last week or so I have been hacking away at improving the simulability of the C65GS, with the direct intention of tracking down bugs much more quickly.  In particular, I have been wanting to get the character generator working again after recently redesigning it to work off a single 8-bit data bus, in preparation for implementing sprites.

It is easy to get VHDL to output text messages at various points, but that can be extremely tedious to wade through as you try to work out if the character generator is fetching one too many or too few bytes during a bad line, or fetching the data from one byte to the left or the right of where it should be.

To make this part easier I wrote a little program that reads the output of the VHDL for me, and then generates a BMP file with all the rendered pixels.  Then I can just look at the static image, see what is wrong, fix it, and repeat the cycle -- in a process that takes just a minute or two, provided you only need to look at the top few rasters of the frame, which is usually enough.

With this in place, I have been able to make much more rapid progress, and already have the character generator mostly working again, as the partially rendered frame below shows.  Excuse the bizarre colours and choice of data.  The main thing is I can see 40 columns being drawn without any significant glitches, and both colour RAM and screen RAM are being addressed correctly:

The purple is the right border, and the text area is currently placed hard-left in the frame, with the left border turned off.  The funny brown stripe is because the right border is still in its normal place, so the space that should have been taken by the left border instead shows up as background colour ($D021).

Now I am just tracking down some simulation bugs that cause the simulation to die before it can draw a complete frame.  Once that is working, I probably have enough of the character generator working again that I can turn my attention back to finishing the re-implementation of the CPU.

1 comment:

  1. Thanks Paul, these post not only show us your progress with the implementation of C65gs, but are also very instructive about FPGA programming/syntesis.