The screen shot below says it all. Yay! Video output from the CPC2.0!
I promised myself that I wouldn’t post those shaky photos/videos that people seem to post of their game/emulator/screen. Unfortunately, at this time a photo of the screen is the best I can do. Longer term, I’ll get a HDMI capture card from eBay and capture the screens properly, but for now this will have to do as proof of success! Colour bars. I used a simple hardware (Verilog RTL) counter to display the image. It’s not a perfect image, as I could only get 5 bits to work in each colour channel, limiting the image to 32K colours. (Yes, that’s still more than the Amstrad, but I have bigger plans for the UI too!). It was a bit of a puzzler why I could get solid white (see “first image” below) or a graded primary, 256 shades of Red OR green OR blue would be fine, but not the full range 16M, 24bit colour. I read and re-read the ADV7513 programming and hardware guides and tried a whole bunch of register settings, but could not encourage a video signal to display when I was using more than one video channel. I managed to get 256 shades of yellow to work a few times (Red and Green), but not reliably. I concluded that the 0.1uF bypass capacitors specified in the ADV7513 hardware users guide were actually needed. I figured that the digital lines are very noisy without those bypass capacitors the colour data on the very fast TMDS lines was getting distorted and sending illegal 8b/10b LVDS codes to the monitor, causing it to shutdown if more than one channel was in use. In the end through trial-and-error, I figured that using only 5 bits per channel caused few enough transitions that the signal made it to the monitor correctly. This was only 800×600 (400MHz TMDS lines), imagine trying to send 1080p traffic!
So the lesson learned here is the bypass capacitors cannot be shared between power lines. They are likely not wired together internally in the chip. If the hardware user guide specifies a 0.1uF bypass capacitor, then you’ll need it. The next revision of the board will fix this and I should be able to use the full 16.7M colour range. I’ll also need to add some bypass capacitors to the FPGA IO power lines, as I realised there are a sum total of zero on these important power supply lines. You may recall I made a layout error on the SDRAM footprint of the last design and had to omit this chip from the board. My guess is that this high speed device will add so much noise to the FPGA IO that it will disturb everything else that’s currently working, so I’ll add the proper bypass for the next revision to avoid any issues.
The board design is divided into three (see the image below). The left most part is the supervisor and bootstrap for the FPGA. Once the FPGA is booted, it is only required for it’s debug connection. The center section is the FPGA and memory part. The memory is missing due to a fault on this board revision, the FPGA was the second part to be proven. The video section is the final part (I’m ignoring the USB chip for now). Now that this has been proven, the main components on the board are tested and shown to work.
Still to be tested are the USB host chip, but I’ve used this before to some success and the Atmel security module (I don’t anticipate problems here, there’s only three pins after all). The successful output of video makes me a lot more confident that the design is sound.
While I could generate a test pattern OK from the FPGA, I couldn’t really output a frame buffer yet because this would require the SDRAM chip to store the 832 x 576 x 24b image and this isn’t working. The plan is to revise the hardware and build a new board, and while I’m waiting for this to arrive, I’ll continue on with the CPC RTL.
I’ve also decided there’s enough memory in the Altera chip to keep both the support CPU ROM and the CPC base 64K on-board. This will greatly help the timing because the CPC video image can only be run from the base 64K and I can make this 2-port RAM if it’s onboard, easing timing constraints. There are 1700Kbits of memory on the FPGA, so the plan is to allocate 64Ko to the support CPU and 64Ko to the CPC CPU which should accommodate the base CPC464 system, plus 32K for the basic and lower rom and leave 47Ko for cache for the video ram buffer and any extended memory and ROMS. This should eliminate the risks of wait-states for memory for most basic applications. This configuration is my first goal.
Sharp eyed readers may notice that on previous images, the HDMI and USB connectors were not present. I had to hand solder these for the HDMI test. The HDMI connector wasn’t easy. I decided that future productions would go through my infra-red oven as hand soldering this 0.5mm pitch connector is prone to problems. The method I used is to blob solder paste across the pins and wick excess solder out with solder braid. I suspect this may have an impact on the performance of the HDMI colour channels as well, so future builds will have this on board at the time of the first IR bake.
I replaced the missing 50MHz clock so that I could generate a stable video signal, and managed to stuff this up on my first attempt. This device is only about 2mm square, so while I got the orientation right (this time), I don’t think it was correctly placed, as I didn’t get a clock signal through. I desoldered this and tried a second chip before I got success. I used aluminium foil to protect the rest of the board when applying the hot air pencil to the components. This prevents the air disturbing existing components and also reduces the heat reaching these components. I’d read this somewhere and figured it sounded sensible. It seemed to work.
The supervisor software was a bit of a problem, as my JTAG connection stopped working after I’d updated the board, so debug was challenging. I’d anticipated that something would stop working, so I’d built a software upload option from the supervisor:
This allowed me to update the support ROM without the aid of the JTAG connection. I’d been using JTAG and a USB blaster for it’s in-circuit memory editing capability. With much trial and error (look at the build number below), I had a working support system. The critical challenge with the ADV7513 video is that when the monitor is turned off and back on, it reset key registers, so this state needs to be detected and the correct register sequence issued when this occurs.
I finally got this to work reliably. It’s not as simple as turning the monitor off and back on to check all is working, it has to check for the power up sequence of the FPGA, is the monitor on or off when power up, is the cable unplugged when power on and all combinations of these items. The code I posted seems to be reliable after about a week of testing and tweaking.
All code is posted on GitHub of course, so feel free to take a look. It’s not intended to be ‘model’ code, but good for reviewing the principals of where I’m up to.
Things should move rapidly now because I already have built a proof of concept CPC core for the Cyclone GX starter board that ran my Amstrad CPC RTL. I’ll copy a lot of that work into this code base now and the next post, I’m hoping I’ll be able to show you the Amstrad boot screen!
Side project – Terasic DE10 Nano
I built this CPC HDL proof of concept originally on the Terasic Cyclone V GX starter kit. This board was far too large for my objective of creating a new generation CPC. I needed a small board with HDMI that would sit behind your TV. So I designed and built the board you see above. However, given enough time everything you want will be conceived and built by someone, somewhere. Terasic have come out with a new board the DE10-Nano kit. This has all the elements that I wanted for this build, a HDMI connection, USB host, on board memory, onboard storage and an ARM supervisor.
I’ve ordered one of these for my development process as it has all of the critical elements such as JTAG and configuration built and ready to go. I expect that this board will be my development board going forward and I’ll create a hardware abstraction layer to separate the CPC2.0 hardware from the DE10 Nano. I’ll post an update on this when it arrives (on Monday according to DHL).