I have a feeling that may be because the VGA screen is actually 480 pixels deep (although we halved the pixel clock, we’re still drawing the same number of lines)… so there’s some code to halve the Y value coming from the VGA sync generator. If the same code has been moved across to the OLED module then it might help explain what’s going on.
This is my second Verilog module ever, so it is probably worth a complete re-write…
I have only been writing Verilog since earlier this year and most of my early attempts were awful, and I still struggle. It is hard.
I still haven’t quite got things to work. This is my closest attempt:
Battery operated, and with working button control:
@gundy was right about the problem with the vertical stretching. I thought I had investigated that and discounted it, but I was wrong. I got the width parameter wrong in the above build. Unfortunately builds take a long time on my rather slow Linux box and for most of them, the screen does not work for reasons I don’t yet understand. Also some of them fail to route. So the development process is very slow.
I am very close to having a fully working version but can’t quite get there.
Your code is mainly clear and good - there just seem to be minor problems with it.
The boards are here!
It looks and feel pretty good, the screen and audio are working (I didn’t test the buttons yet).
In this proto version the screen mounting is a bit goofy:
Also the TinyFPGA with female and male headers is higher than the battery holder. Which means that when the board is on a table, it is resting on the TinyFPGA board. I’m not sure how to fix that.
The cost (without the screen and TinyFGPA):
- PCBs : 62,23 euros
- PCBs import taxes: 29,5 euros
- Parts (mouser): 121,23 euros
Total for 5 boards: 212,96 euros
Total for 1 board: 42,5 euros
Looks good. I would like one please. How do we pay you for them? Are you planning to assemble them?
On my hand-soldered one, I found that it was easy to accidentally press the reset button on the TinyFPGa so I connected some spacers to the PCB to protect it.
Put me down for a board too - I’m happy to assemble myself if it’s easier
We can use Paypal. Everyone interested can contact me direct message for the details.
(I only have 4 boards available for now)
I don’t really have time for that. It is very easy though so don’t worry.
Quick update: I’ve finally managed to get a version synthesised that has video, audio & gpio all working… and even managed to just squeak in at 17.1MHz timing… it’s been quite a fight to get it all to fit though, and naturally some things had to be sacrificed…
For one, the LCD CS, RW and backlight enable pins were all sacrificed - they were essentially constant drivers anyway.
On the audio side of things, some sacrifices were made:
- it’s still 4 channel, and there are still 4 available waveform generators (square, saw, triangle, noise), but…
- each channel’s waveform generator now produces only 6-bit output (down from 12)
- there is no ring modulation or sync support
- channel (and global) volume controls are now 4-bits instead of 8.
- pulse-width selection for square waveform is now 4-bits instead of 12.
- the phase accumulator width has been trimmed, and with it the sample rate (from 1MHz - which was way overkill anyway), to 62500Hz.
It’s not great, but it could have been worse
On the video side, fewer sacrifices were made, but the code is now incompatible with the VGA sync generator as I made a few changes to simplify the code somewhat. Turns out there were lots of savings to be made just by rearranging the way things like hsync/vsync worked.
I’ve also trimmed the number of available colours from 256 down to 64. (RRGGBB instead of RRRGGGBB). As well as allowing me to save a few gates, I believe this also allowed me to create a better palette with better neutral greys.
I’ve also added a raster interrupt register, that allows one to trigger an interrupt based on the y position currently being rastered out. This means that, in theory, it should be possible to set an interrupt at a particular line, and do things like swapping out the palette, or sprite pointers, or a bunch of other fun things (eg. if you want more than 8 sprites, or more than the standard 16 colours you should be able to swap to a new set every 16 lines if you can process the interrupts fast enough)… Actually, this should allow you to do things like have multiple non-scrolling windowed areas on the screen at one time too.
Although the demo below doesn’t look much different to last time, there’s been a surprising amount of work that’s gone into it
Now it’s time to start working on some C and assembly code again