So you need to double (or triple, or quadruple) the clock speed...

edited June 2010 in Hardware
No particular reason for posting this, other than I was looking at an eZ80 evaluation board that does this, and that jogged my memory of a project I'm thinking of doing over the winter. And that I've seen the odd project here that's needed to use a faster clock than the 3.5MHz one you find at the edge connector, so they've soldered a wire to the 14MHz clock that drives the ULA... so I think for anyone contemplating such a project, this may save them from having to solder things to their Speccy motherboard. So a quick primer on clock multiplication is in order.

So: Problem - you want to make some sort of device. It needs a clock that's faster than the Spectrum's (say, 7MHz or 14MHz or 28MHz) but is synchronized with the Spectrum's 3.5MHz clock.

Clock *dividers* are easy, and amazingly common, and are by their nature synchronized with the master clock. A single D-type flip flop will nicely give you half the frequency of the master clock. Two D-type flip flops will divide by 4, etcetera. They are easy because you just clock the flip flop with the 3.5MHz master clock, and away you go. But you can't trigger where there is no edge. This makes multiplying a little bit more challenging.

The solution: Another oscillator of the frequency you want, that's somehow kept in sync with the master clock.

The method: Something called a phase locked loop. Effectively, what you have is a voltage controlled oscillator and a phase comparator. The VCO is set to oscillate at the frequency you want, and if it gets ahead of the master clock, the phase comparator changes the control voltage to slow the VCO slightly until it comes back in sync. If the opposite happens, the phase comparator does the opposite and speeds the VCO slightly to get it back in sync. Here's a block diagram of what you do:

The divide-by-N stage is (somewhat paradoxically!) how much you want to multiply the signal by. If you want to double it, you divide by 2. If you want to quadruple it, you divide by 4. So if you wanted to make a 14MHz clock from the 3.5MHz input, you'd divide by 4.

To demonstrate this working, I used a 74LS629 voltage controlled oscillator, a 4MHz crystal oscillator and an Xilinx XC9536 in which I built the phase comparator out of digital logic. There's actually a chip to do all of this (74HC4046, which has the phase comparator and VCO all in one chip) which I would have used if I have one, but I don't. (And I'd recommend you use one for things like this since they cost 25p from Farnell and will save you having to either use a bunch of macrocells in your CPLD, or soldering a heap of 74-series logic to make your phase comparator). But in any case it's interesting to understand how these things work. The phase comparator looks like this:

Here is how the phase comparator works. It's built out of two D-type flip flops and a few gates, and a couple of 3 state output drivers (which are connected together off chip and passed through the low pass filter).

The top flip flop is clocked by the reference clock (i.e. your 3.5MHz clock if you're using a Spectrum, but for the demo, it was 4MHz). The bottom flip flop is fed by the VCO divided by N, in this case, divided by 2 by the counter (CB4CE's first output) in other words, this is set up as a frequency doubler which will give an 8MHz output. The counter is of course fed by the actual VCO's output, the 74LS629.

If both clocks are perfectly in step, you'll have a 4MHz input going to both flip flops. Note that the D (data) pin of each flip flop is hard wired to logic 1. So on the low-to-high transition of each flip flop, it will get set to 1. The output then goes to an AND gate, which in turn resets the flip flops asynchronously. So if both flip flops go high at the same time, they just get immediately reset. In other words - should the two clocks be running in sync with each other, the flip flops get reset straight away.

Now imagine the VCO has a frequency slightly higher than 8MHz. What will happen is that pretty soon, the two signals will start going out of sync - in other words, out of phase. The VCO will start to lead the reference clock. This means the bottom flip flop will spend some time with its output at logic 1 before the reference clock's flip flop reaches logic 1 and resets both flip flops. This in turn will turn on the output buffer and will mean the pin LEAD_L is no longer floating, and will be grounded.

If the opposite occurs - the VCO is slightly slow - the reference clock's flip flop will spend some time outputting a logic 1, which will turn on the LAG pin - it will no longer float but instead be connected to 5v.

The upshot is that if you tie LEAD_L and LAG together, whenever the VCO is running slightly ahead of the reference clock, there will be a 0 volt output pulse proportional to how far it's out of phase. If the VCO is running behind, there will be a 5 volt output pulse proportional to how far it's out of phase. If the two are in sync, there are no pulses (well, none worth worrying about) and the circuit just floats.

Pass these through a low pass filter, which is just a capacitor and resistor - effectively a simple digital to analogue converter (see some of the discussions on how to make analogue waveforms with the Spectrum's speaker for more on this) - and you get a voltage that increases the longer and more frequent the +5v pulses are, and a voltage that decreases the longer and more frequent the 0v pulses last. This then goes to the input pin of the voltage controlled oscillator, y et voila, we have an 8MHz signal that is kept in sync with the 4MHz master clock. Indeed, this is exactly how one of the phase comparators in a 74HC4046 actually works.

(There is a bit of jitter on my circuit as built, about 15ns or so. I suspect a 74HC4046 will perform much better, and it doesn't help that my circuit is built on breadboard - the voltage changes to control the oscillator are tiny and just moving the breadboard away from my computer changed the nature of the jitter Update: I got the jitter down pretty much to zero by tinkering a bit with the low pass filter).

Here's the output from the circuit, the top trace is the 8MHz output from the VCO, the bottom is the 4MHz reference clock.

It's worth noting that if you divide the reference clock down by, say, 16 - you can synthesise all sorts of frequencies with a circuit like this, not just powers of two of the reference clock that are kept in sync with your accurate crystal oscillator.

And here is the breadboarded demonstration circuit:

Note my breadboard isn't as tidy as csmith's Harlequin :-) The chip on the top left is the 74LS629. The green wire is the control input (voltage from the low pass filter). The low pass filter itself can be seen just below the PCB with the CPLD (the capacitor is hidden by the oscilloscope probe). The frequency setting capacitor for the 74LS629 is just below the green wire to the left of the chip.

The bottom left chip is a schmitt trigger inverter and it's here for two reasons - to improve the wave form (make it more square) from the 74LS629 and give it proper 5 volt swings and also to provide the 4MHz crystal oscillator circuit which is the reference clock. (The two capacitors are just the load capacitors for the crystal oscillator). The CPLD is an XC9536, but this could easily be done in discrete logic.

When using a 74HC4046, you still need the external low pass filter and the frequency setting capacitor to set the mid point of the VCO, and of course a reference clock. The '4046 also provides a choice of three kinds of phase comparator, one of which is a simple XOR gate.
Post edited by Winston on

• edited June 2010
I also thought about having a different clock for the Z80... Thught about frequency multipliers and the like. Then I realized that Amstrad changed the way the Z80 and ULA are synchronized each other, by using the WAIT signal. That makes things easier, I guess.

I've bought some Z80's rated up to 20MHz to do a quick test. The test was meant to use the 8,8MHz color clock to feed the CPU, but didn't work as expected :(

It happens that RAM accesses are controlled by ULA (both VRAM and non-contended RAM), and I'm afraid that the ULA generates the RAS and CAS signals using its own internal references. An overclocked CPU may have problems reading or writting to a RAM address which is accessed as if the CPU was running at 3.5MHz. Nevertheless, I have to check it out.

My idea, applicable to pre +2A/+3 models, is to have two clock sources for the Z80A. The original one, and the fast one. A logic circuit examines what kind of bus access is to be performed, and if it's a VRAM memory access (or a ROM access, to keep LOAD/SAVE compatibility), then the original clock is used. On the other way, if a non-contended RAM access is to be performed, the "fast" clock version is used. Changes would need to be applied to the RC cell that generates the RAS-to-CAS delay, and perhaps, faster DRAM's are going to be needed.
• edited June 2010
See bitcycle.org/retro/msx/super_turbo/ - I'd give it a good chance of working if placed between ULA's Z80 clock output, and Z80's clock input. Perhaps with a few connections to lower clock speed at proper points in time. Above circuit can switch a Z80 clock between unrelated clock sources (believe me, that isn't easy!). ;)

Indeed it's a bummer the ULA resolves Z80 <-> video conflicts by fiddling with Z80's clock signal, as opposed to inserting a wait cycle here & there. I suppose an easier way would be to start with the 14 MHz. signal that ULA takes as input - you could use some flipflops to obtain 7 & 3.5 MHz. clocks which are synchronized with ULA. That could simplify clock switch circuit a lot - but you'd still have to deal with the ULA's cycle-skipping somehow. And watch the output voltage levels: normal logic levels may work, but Z80 datasheets say you need low & high very close to supply rails. Read: if you use a CPLD like Xilinx XC9536 to generate the clock signal, it may work but you'd run your Z80 out of spec, even with a higher-speed version.

Dividing a common clock sounds easier to me than using a PLL to multiply a previously divided clock - remember that ULA's clock output isn't a clean 3.58 MHz. signal (so a PLL might not work very well with it).

Also the fact that ZX Spectrum's video memory is part of the normal Z80 memory space, complicates things. But I have no idea how big a problem that really is.
I've bought some Z80's rated up to 20MHz to do a quick test. The test was meant to use the 8,8MHz color clock to feed the CPU, but didn't work as expected :(

You might have better luck with an 8 or 10 MHz. Z80. Using a 20 MHz. version sounds nice, but timing of control signals may change enough to cause problems. Also outputs switch much faster, which may cause overshoot/undershoot problems. Read: signals may take longer to stabilize vs. a lower-speed part. I've had a 20 MHz. Z80 on a ZX81 board recently and can confirm that works. But that was on ZX81's normal 3.25 MHz., and a Spectrum is not a ZX81...
• edited June 2010
Dividing a common clock sounds easier to me than using a PLL to multiply a previously divided clock - remember that ULA's clock output isn't a clean 3.58 MHz. signal (so a PLL might not work very well with it).

The problem with that is that the only clock at the edge connector is the 3.5MHz one - the 14MHz one can't be accessed unless you take the Speccy apart and start soldering wires on, and the point of this is to avoid having to do anything other than plug something into the edge connector. We might be happy soldering stuff to the 14MHz crystal, but "normal people" can't be doing with soldering wires onto parts of their Speccy :-)

The biggest problem with the pre-Amstrad models would be if the ULA clock stopping wound up inverting the phase of the clock relative to where it would have been had it not been stopped. Fortunately, this doesn't happen (and they'd have had to work at it to make it happen). The challenge, therefore, is to make the VCO stable enough (and of course its voltage input high enough impedance not to load down the low pass filter enough to make its voltage fall significantly, and thus reduce the frequency output of the VCO) so it can go the maximum number of T-states that contention lasts without getting unacceptably far out of sync. I'm not sure my lash-up job with the 74LS629 would be good enough (especially considering the low pass filter has a TTL load on it), but the 74HC4046 might be good enough.

As for the ULA's clock output, it actually generates significantly less harmonics than the Amstrad +3 one (which is much cleaner, with much faster rise and fall times) :-) So it may be less of a problem for a PLL (especially if you were to use one prone to locking onto a harmonic). If the ULA's clock rise time is too slow, well, a single gate schmitt trigger buffer will fix that (so long as the propagation delay won't kill your application).

There are instances where you need a faster clock (say, if you want to be able to clock 8 bits of data from a serial device before a Z80 I/O cycle finishes) where being kept in sync with the Z80 is less important - for instance, there you may just use a free running 20MHz crystal oscillator, and let the output side of the shift register just see the Z80 I/O timings once the 8 bits are loaded, which at that speed will be well before IORQ goes back high.
normal logic levels may work, but Z80 datasheets say you need low & high very close to supply rails. Read: if you use a CPLD like Xilinx XC9536 to generate the clock signal, it may work but you'd run your Z80 out of spec

The XC9536 does provide full 0v to 5v swings (it's a 5V chip) and the datasheet allows down to Vcc-0.6v on the clock pin. Perhaps you're thinking of the 3.3 volt XC95xx-XL :-) In which case all you need to add is a single gate buffer like a 74HCT1G125 between the CPLD output and the Z80's CLK pin.
• edited June 2010
Out of curiosity (and because I've not yet de-breadboarded this little experiment) I had a look to see what happens when I use a rubber keyed Speccy 48K's CLK signal from the edge connector. The PLL does indeed lock on OK, but there's quite noticable jitter if a lot of contention happens in a very short space of time. It'll be interesting to find out how a 74HC4046 does in comparison (judging by the datasheet, quite a lot better I would hope).
• edited June 2010
Winston wrote: »
We might be happy soldering stuff to the 14MHz crystal, but "normal people" can't be doing with soldering wires onto parts of their Speccy :-)
Sorry, I missed that "can't touch the Speccy's internals" part... :-)
Indeed: as soon as case must be opened, 99% of people are scared off (and rightfully so, -rubber key- ZX Spectrum isn't very solder-friendly, if you take its weak construction / keyboard into account).
As for the ULA's clock output, it actually generates significantly less harmonics than the Amstrad +3 one (which is much cleaner, with much faster rise and fall times)
With not 'clean' I referred to the cycle-skipping aspect - I wouldn't have a clue about how the waveform looks (not that I care btw, as long as it works)... ;)
The XC9536 does provide full 0v to 5v swings (it's a 5V chip)
Ehm yes, I thought so too, being a CMOS chip working @5V internally, but... no it doesn't. I have a sample project here that includes some LEDs. Each drawing ~5 mA (probably more than a Z80 clock input would draw but still not that much), and high level output voltage is ~3.5V. Just check with a voltmeter if you don't believe me (or maybe it depends on production batch). I suppose it has to do something with how the I/O's are constructed to allow 3.3 & 5V output levels. There are some Xilinx docs with typical V vs. I graphs - but it's definitely not close to 5V rail if there's some load on the output. Low level should be okay, and I doubt it would matter if you feed it to Z80 clock input (perhaps a simple resistor could pull-up output to ~5V) - it's just that I generally prefer to design circuits based on specifications, and then test with real parts to see if they do what it says on the box.

Of course none of this is relevant if you're using it externally (vs. feed it to Z80 as clock signal)...
• edited June 2010
Ehm yes, I thought so too, being a CMOS chip working @5V internally, but... no it doesn't. I have a sample project here that includes some LEDs. Each drawing ~5 mA (probably more than a Z80 clock input would draw but still not that much), and high level output voltage is ~3.5V. Just check with a voltmeter if you don't believe me

In which case your CPLD is actually doing better than the datasheet says it should :-)

But that's pretty common with any CMOS chip, and it's why it's recommended you drive LEDs by sinking current (in other words, a common 5v rail for the LEDs, and turn the LED on by setting the output to 0v). Nearly all CMOS chips can sink much more current than they can source, the N-channel FETs typically have a lower (usually by an order of magnitude) Rds(on) than the P-channel ones.

But a Z80 clock pin is a FET input even in the old NMOS versions, that's to say its impedance is measured in megaohms. It's not going to load down a CPLD pin in any significant way and you'll get a good 5 volt swing unless the parasitic capacitance of your board is disastrously high (I think at single digit MHz speeds even a breadboard won't have enough parasitic capacitance to matter). So I don't think that you'll get a clock signal that's out of spec.
• edited June 2010
Reverse the polarity on the flux capacitor and get it up to 88mph ;)