Friday, 20 December 2013

Adventures with Programmable Logic

So I have received the following goodies:
  1. XC9572 x 3 (PLCC44)
  2. Platform Cable USB programmer (Model DLC9G)
  3. Some PLCC44 PCB sockets (through hole)
  4. PLCC44 to DIP44 converter for the breadboard
  5. PLCC extraction tool
The XC9572 is a simple part, by modern programmable logic standards.  Not exactly capable of running a soft processor, the '9572 can still be used for one of the less exciting parts of a computer (at least a small one): glue logic.  It can also, with a suitable design constructed, be used for implementing some fairly complex IO functions.

If I'd relied on a supplier in China for my JTAG programmer I would still be waiting.  After about 4 weeks I finally gave up and ordered another one from a chap in the UK.  This caused me my first small headache: getting the programmer working in a VirtualBox Windows 7 environment.  The DLC9G needs, like many USB gadgets, firmware to be loaded before it can be used.  This causes a problem for VirtualBox as upon loading the firmware the USB product ID changes, which breaks USB pass-through.  The solution is simple enough: manually make the particular vendor and product codes used by the programmer always be marked for use by the Windows VM.

Once that was done, it was time to test out some HDL designs!

But first a word on the various ways of expressing the design to implement.  There a roughly three ways:
  • By drawing a schematic.  In the good old days, this was about the only way.
  • By using a low-level hardware description language like ABEL.
  • By using a "higher" level language like VHDL or Verilog.
My initial efforts focused on ABEL.  This seemed sensible because it most closely describes the actual wiring in the circuit; every connection (more or less) is described in text form.  I figured if I can draw a shift register using flip-flops I can describe it in ABEL.  Combinational logic, too, seemed simple enough.

The initial goal was (and is) to implement the glue logic for the IO "half" of the computer in a CPLD.  This includes the IO decoder enable generator as well as the AY-3-8912 glue.  In other words, these bits of the circuit:

 After reading some tutorials and references on ABEL like these:
I came up with the following ABEL implementation for my IO decoder:

MODULE ioglue

// Defined inputs

ECLOCK pin 1;
WRITE pin 2;
READ pin 3;
IO pin 4;
A0 pin 8;
A4..A6 pin 9,11,12;

// Defined outputs

DUART pin 38 istype 'com'; // /DUART CS
LATCH pin 39 istype 'com'; // /LATCH CS
IDE pin 42 istype 'com'; // /IDE CS
AY pin 43 istype 'com'; // /AY CS
VIA pin 44 istype 'com'; // /VIA CS

BDIR pin 29 istype 'com'; // AY BDIR
BC1 pin 33 istype 'com'; // AY BC1
AY_A0 pin 34 istype 'com'; // AY A0

RESET pin 34 istype 'com'; // RESET


DUART = !(!IO & (!A6 & !A5 & !A4));
LATCH = !(!IO & (!A6 & !A5 &  A4));
IDE = !(!IO & (!A6 &  A5 & !A4));
AY = !(!IO & (!A6 &  A5 &  A4));
VIA = !(!IO & ( A6 & !A5 & !A4));

BDIR = !(WRITE # AY); // NOR
BC1 = !(A0 # AY); // NOR
AY_A0 = !AY;


This is just simple Boolean logic used to implement a decoder, with some NOR gates for the sound IC.  Notice the pin assignments at the top of the file - they tie the inputs and outputs to particular pins on the CPLD.

I'm not quite ready to replace the 74HC138 and NOR gates in the IO breadboard with the CPLD, but after programming a XC9572 I tried out my glue design on the breadboard with some switches and LEDs and all looked good!

The next experiment to further my ABEL skills was to implement some sequential logic.  Probably the simplest thing to implement was a counter. For that I would need a clock source and, predictable, I went for one of the all-time famous ICs; the 555 timer.

At this point things started to go wrong. No matter what I try, I cannot get a counter to work properly. The oddest thing is the fault in all the counters I have implemented: upon counting to binary 1111 (in a 4 bit counter), the next outputted value is not 0000 but 0001, which is obviously not right.  Back to the drawing board then.

The next step is to follow some tutorials in a different HDL and try out some different designs, including counters.  After playing about with Verilog, I have decided to focus my efforts on VHDL instead.  It looks "cleaner" then Verilog (don't ask how).  I certainly need to slow down a bit and start learning again.

Over the next few weeks (the Christmas holidays) I hope to follow some very interesting looking tutorials that I've found, and achieve a working counter.  There is not really much point in trying to do more complicated things until this is done.

In the meantime, to prove that the XC9572 will work in my 8 bit computer project, I have implemented someone else's design in my CPLD.  The 65SPI is a SPI bus driver, implemented in ABEL by Daryl Rictor, and intended to implemented in a XC9572.  After playing with it for a few days, I've come to the conclusion that is an amazing piece of HDL.  It has 8 Slave Select outputs, multiple speed options, and is really easy to program. Here it is plugged into the breadboard, replacing the 6522 VIA which was performing SPI duty:

As before, the SPI controller is interfaced to a DS1305 Real Time Clock.

Code for talking to the 65SPI is implemented in the assembly file spi.asm, and replaces the previous bit-banging on the VIA.  Interestingly, I tried exactly what I described previously in this blog whereby I did not recompile my setclock.asm and showclock.asm user programs, and instead changed the implementation of the SPI AI from bit-banging to talking to the 65SPI, and (as I hoped and expected) everything worked just perfectly.  The "user level" code neither knew or cared that the implementation for the SPI interface was changed.

One of the interesting things about using the 65SPI is that SPI is now much faster.  As can be seen in this grab from the Logic Analyser, it is now so fast that the 6809 cannot keep up:

The SPI clock line is now running at 500Khz (on a 4Mhz 6809), which is at least 10 times faster then was achieved when bit-banging.  As can be seen, it is so fast that the 6809 cannot supply data fast enough. This is because of two things: polling for the 65SPI going into the idle state before it loads the next byte (this polling loop could probably be replaced with a couple of nops (no operation)), and actually getting the bytes to send from memory.  Even with the large gap between bytes, the 65SPI is still at least 5 times faster then I achieved with the bit-banging approach.

The 65SPI is very flexible and I've only just started to learn about it's subtleties. One thing you can configure is the data rate, by dividing the clock down by a configurable amount.  It also has a "fast" mode, which I've yet to play with.  All in all the 65SPI is a kind of model for me to follow with what I want to do with the CPLDs in my computer.  One thing is to see if it's possible to implement a I2C bus-driver in the same way.  I2C is quite a bit more complicated then SPI though, so it may not be possible.

But this is far in the future.  In the mean time, I have ordered some more DIP adapters so I can play with one of my other XC9572 and try, once again, to implement some simple sequential logic, starting with getting a fully working counter.

In "other news", I have received a replacement CompactFlash and a couple of 8Mhz 6809s.  At some point I will solder up a new "computer PCB" and switch back to a 8Mhz core computer, laying to rest the ghosts of blown up parts caused by a mistake with a power supply.

I have not much time before Christmas to get my computer to play Christmas music, so I will focus on that for the next few days....