Moving the programmable wait-state generator into a GAL22V10

It was previously decided that the AVR could not respond fast enough to a DISK or UART chip select signal by asserting the Z-80’s WAIT line while the AVR serviced the Z80’s I/O request. Thus, a wait-state generator was needed. More precisely, a programmable wait-state generator, so the design criteria was to create a programmable wait-state generator that could be controlled by the AVR.  In my calculations, I needed to figure out just how many  wait-states were needed for each of the Z80’s available clock speed.

After the failed attempts as using a ATF16V8 SPLD for the programmable wait-state generator, I knew I needed to be able to preset the Q outputs high again once the wait-state sequence was finished, thus leaving the shift-register ready for the next high to low transition of the Z80’s IORQ line.  The 16V8 and 20V8 series of SPLD’s simply has no way to access PR and CLR lines on the registers.  However, the 22V10 series does.  I received four of the GAL22V10D’s last week so I was ready to move this design over (and forward).  Besides, the 22V10 has two output pins that can handle up to 16 product terms, which would come in handy if I can also squeeze the address decoded logic into the same physical package as the programmable wait-state generator.

I transferred the programmable wait-state generator CUPL code over to fit into a GAL22V10D.  The Z80;s IORQ line is fed into the “shift in” (SI) of the 1st shift-register, so normally, the SI input is at a “1”.  Once the IORQ line is dropped low, a “0” is fed into the SI input and the wait-state “counter” is started, thereby shifting a “0” sequentially through the shift-register chain.  The GAL22V10 series supports “asynchronous clear” and “synchronous preset”.  In my design, I connected the “synchronous preset” of all the registers to the sum of the counts for each wait-state so that once the sequencer has finished its required count(s), the “counter” is reset back to “0xFF” thereby forcing all Q outputs back to “1”, ready to start a new wait-state sequence.  At that same time, the WAIT line is un-asserted and the Z80 can finish its I/O cycle, thus releasing the IORQ line back to presenting a “1” on the SI input again.  I tested the functionality in the simulator and all looked good, so I programmed a GAL22V10D and plugged it into my “functional test board”  with a Z80 to drive it.

I was able to run the test code on the AVR with the AVR DRAGON as my real-time debugger.  With the AVR DRAGON, I can fiddle the individual bits in the I/O registers.  I changed the OCRA0 register to change the toggle rate of the OCA0 output, which drives the Z80’s clock pins at the various clocking frequencies.  I am also able to toggle the S1 and S0 pins to select the correct number of wait-states from the GAL22V10D and its effects can be seen on my oscilloscope and the capture from the logic analyzer.

Using the logic analyzer and as expected, the PLD design worked because the registers were now being preset back to a logic “1” after a the wait-state sequencer was finished.  Yea!

I used the logic analyzer to measure the WAIT assertion times, which are:

8 MHz = 7 ws = 1120 nS
4 MHz = 4 ws = 1240 nS
2 MHz = 2 ws = 2000 nS
1 MHz >= 0 ws

I needed at least 875nS for the AVR to respond to the interrupt and assert the Z80 WAIT line, so these timings fall within the specification for the WAIT line setup and hold times and they do delay the Z80 I/O access cycle by the needed duration for the AVR to take over and continue asserting the Z80’s WAIT line, even after the wait-state generator has served its initial function of seizing the Z80 WAIT line.

The following images are actual logic analyzer captures of the Z80 running with an 8MHz clock.  In the 1st image, there are “0” wait-states inserted.  In the 2nd image, there are “7” wait-states inserted.

The duration of the active low “M1” signal is shown in the upper right corner as the difference between the “A” and “B” bars.  At 8Mhz/0Ws, the M1 active duration is 240nS.  At 8MHz/7WS, the M1 active duration is 1120nS.  (Note: The “M1” signal is in yellow, as is the “A Bar”, so it is difficult to see that the “A Bar” starts on the falling edge of “M1” and the “B Bar” ends on the rising edge of “M1”. The “count” values are on the line labeled as “QSTATE” and are the inverted values used to determine what “count” each wait-state is active for.  The “Q” outputs are also show below “QSTATE” and as can be seen in the 7WS image, the WAIT line is asserted (active low) until Q7..Q0 = 0x00 at which point the Q outputs are preset back to “1” and the WAIT line is released.  The AVR should respond before the programmable wait-state generator releases the WAIT line.  Since the programmable wait-state generator’s WAIT line is tri-stated after the wait cycle is completed, there is no contention between the programmable wait-state generator and the AVR driving the WAIT line low.

_wait_state_generator-8mhz-0ws_live
Actual logic analyzer capture of the Z80 running at 8MHz with 0 wait-states inserted.
_wait_state_generator-8mhz-7ws_live
Actual logic analyzer capture of the Z80 running at 8MHz with 7 wait-states inserted.

The PDF file of the 1st image is here: wait_state_generator-8mhz-0ws_live.

The PDF file of the 2nd image is here: wait_state_generator-8mhz-7ws_live).


I was hoping to add in the memory decoder but I do not have enough outputs available on the GAL22V10D since I am using 9 of the 10 available outputs.

I’ll just put the memory decoder into the GAL16V8B along with some other “glue logic” that I have on the board, which is basically a few 74HC04 inverters.

Below are the CUPL design file (WSGen-1v00.PLD), the resulting compiler output (WSGEN-1V00.doc) and the simulator’s test vectors (WSGEN-1V00.so).

Note that this design could easily be expanded to select from 0 to 7 wait states by adding an “S2” pin and modifying the MUX equation to add the additional 4 select states (3-of-8 decoder).  Also note that the select inputs can be directly strapped to VCC and GND if there is no need to use this feature under MCU control.

In addition, if need be, I can add an 8th shift-register to gain an additional 8th wait-state if needed because I have a spare output pin on the GAL22V10D.

In the CUPL design file, I have created “intermediate variables” for all wait-state combinations of 0 to 7 wait-states.  In the final definition for the WAIT output, I select how many wait-states I wwant and insert it into the WAIT output’s decoding logic equation.  This makes it easy to make simple changes to each of the select inputs function.

Next up, programming the memory and I/O address decoder PLD.

/* File Name:WSGen-1v00.PLD */
Name Wait_State_Generator;
Partno ;
Revision 01;
Date 10/15/2016;
Designer Quest, Johnny;
Company JQ;
Location None;
Assembly Z80 Computer;
Device g22v10;

/* Note that this design could easily be expanded */
/* to select from 0 to 7 wait states by adding an */
/* "S2" pin and modifying the MUX equation to add */
/* the additional 4 select states. Also note */
/* that the select inputs can be strapped to VCC */
/* and GND if there is no need to use under MCU */
/* control.

/* Selectable wait-state generator
 *               ______________
 *              | Prog WS Gen  |
 *  Z80_clk x---|1           24|---x Vcc 
 *       s0 x---|2         8 23|---x q7 
 *       s1 x---|3        10 22|---x q6 
 *     mreq x---|4        12 21|---x q5 
 *     iorq x---|5        14 20|---x q4
 *          x---|6        16 19|---x !wait
 *          x---|7        16 18|---x 
 *          x---|8        14 17|---x q3 
 *          x---|9        12 16|---x q2 
 *          x---|10       10 15|---x q1 
 *          x---|11        8 14|---x q0 
 *      GND x---|12       SP 13|---x 
 *              |______________|
 */

/* Inputs */
PIN 1 = Z80_clk; /* Z80 system clock */
PIN [2,3] = [s0,s1]; /* Wait-State Select inputs (active high) */
PIN 4 = mreq; /* Z80 MREQ (active low) */
PIN 5 = iorq; /* Z80 IORQ (active low) */
PIN 6 = avr_cs; /* AVR chip-selected (active low) */

/* Outputs */
PIN [23..20] = [q7..q4]; /* Registered outputs (buried nodes) */
PIN 19 = wait; /* wait-state output (active low) */
PIN [17..14] = [q3..q0]; /* Registered outputs (buried nodes) */

/* Intermediat variables */
FIELD select = [s1..s0]; /* wait state select inputs */
FIELD count = [q7..q0]; /* comparison counts */

si = iorq # avr_cs; /* Shift in */

/* For desired wait states, choose from the following */
/* equations, then substitute in WAIT equation below. */
ws0 = (count:[00]);
ws1 = (count:[FE]);
ws2 = (count:[FE] # count:[FC]);
ws3 = (count:[FE] # count:[FC] # count:[F8]);
ws4 = (count:[FE] # count:[FC] # count:[F8] # count:[F0]);
ws5 = (count:[FE] # count:[FC] # count:[F8] # count:[F0] # count:[E0]);
ws6 = (count:[FE] # count:[FC] # count:[F8] # count:[F0] # count:[E0] # count:[C0]);
ws7 = (count:[FE] # count:[FC] # count:[F8] # count:[F0] # count:[E0] # count:[C0] # count:[80]);

/* Equations */
/* Shift register */
q0.d = si; /* Shift input */
q1.d = q0;
q2.d = q1;
q3.d = q2;
q4.d = q3;
q5.d = q4;
q6.d = q5;
q7.d = q6;

/* Shift Register Syncronous Preset using IORQ */
q0.sp = iorq;
q1.sp = iorq;
q2.sp = iorq;
q3.sp = iorq;
q4.sp = iorq;
q5.sp = iorq;
q6.sp = iorq;
q7.sp = iorq;

/* Shift Register Asyncronous Reset not used */
q0.ar = 'b'0;
q1.ar = 'b'0;
q2.ar = 'b'0;
q3.ar = 'b'0;
q4.ar = 'b'0;
q5.ar = 'b'0;
q6.ar = 'b'0;
q7.ar = 'b'0;

/* Shift Register Output Enable */
q0.oe = 'b'1;
q1.oe = 'b'1;
q2.oe = 'b'1;
q3.oe = 'b'1;
q4.oe = 'b'1;
q5.oe = 'b'1;
q6.oe = 'b'1;
q7.oe = 'b'1;

/* Wait-State Select MUX */
!wait = select:[0] & ws0
 # select:[1] & ws2
 # select:[2] & ws3
 # select:[3] & ws7;

wait.oe = !iorq; /* enable WAIT output */
/* File Name: WSGEN-1V00.doc */
*******************************************************************************
 Wait_State_Generator
*******************************************************************************

CUPL(WM) 5.0a Serial# 60008009
Device g22v10 Library DLIB-h-40-1
Created Tue Oct 18 22:40:16 2016
Name Wait_State_Generator
Partno 
Revision 01
Date 10/15/2016
Designer Quest, Johnny
Company JQ
Assembly Z80 Computer
Location None

===============================================================================
 Expanded Product Terms
===============================================================================

count =>
 q7 , q6 , q5 , q4 , q3 , q2 , q1 , q0
q0.d => iorq
q0.ar => 0
q0.oe => 1
q0.sp => iorq
q1.d => q0
q1.ar => 0
q1.oe => 1
q1.sp => iorq
q2.d => q1
q2.ar => 0
q2.oe => 1
q2.sp => iorq
q3.d => q2
q3.ar => 0
q3.oe => 1
q3.sp => iorq
q4.d => q3
q4.ar => 0
q4.oe => 1
q4.sp => iorq
q5.d => q4
q5.ar => 0
q5.oe => 1
q5.sp => iorq
q6.d => q5
q6.ar => 0
q6.oe => 1
q6.sp => iorq
q7.d => q6
q7.ar => 0
q7.oe => 1
q7.sp => iorq
select => s1 , s0
!wait => !q0 & q2 & q3 & q4 & q5 & q6 & q7 & s0
 # !q0 & !q1 & q3 & q4 & q5 & q6 & q7 & s1
 # !q0 & q2 & q3 & q4 & q5 & q6 & q7 & s1
 # !q0 & !q1 & !q2 & !q3 & !q4 & !q5 & q7 & s0 & s1
 # !q0 & !q1 & !q2 & !q3 & q5 & q6 & q7 & s0 & s1
wait.oe => !iorq


/* File Name: WSGEN-1V00.so */
CSIM(WM): CUPL Simulation Program
Version 5.0a Serial# 60008009
Copyright (c) 1983, 1998 Logical Devices, Inc.
CREATED Tue Oct 18 22:40:16 2016

LISTING FOR SIMULATION FILE: WSGEN-1V00.si

 1: Name Wait_State_Generator;
 2: Partno ;
 3: Revision 01;
 4: Date 10/15/2016;
 5: Designer Quest, Johnny;
 6: Company JQ;
 7: Location None;
 8: Assembly Z80 Computer;
 9: Device g22v10;
 10: 
 11: /* Selectable wait-state generator
 12: * ______________
 13: * | I/O Decoder |
 14: * Z80_clk x---|1 24|---x Vcc
 15: * s0 x---|2 8 23|---x q7
 16: * s1 x---|3 10 22|---x q6
 17: * mreq x---|4 12 21|---x q5
 18: * iorq x---|5 14 20|---x q4
 19: * x---|6 16 19|---x !wait
 20: * x---|7 16 18|---x
 21: * x---|8 14 17|---x q3
 22: * x---|9 12 16|---x q2
 23: * x---|10 10 15|---x q1
 24: * x---|11 8 14|---x q0
 25: * GND x---|12 SP 13|---x
 26: * |______________|
 27: */
 28: 
 29: FIELD count = [q7,q6,q5,q4,q3,q2,q1,q0];
 30: FIELD select = [s1,s0];
 31:
 32: ORDER: Z80_clk, %3, mreq, %2, iorq, %3, s1, %2, s0, %3, q0, %2, q1, %2, q2, %2, q3, %2, q4, %2, q5, %2, q6, %2, q7, %2, wait;
 33: 

====================================================
 Z 
 8 
 0 
 _ m i w 
 c r o a 
 l e r s s q q q q q q q q i 
 k q q 1 0 0 1 2 3 4 5 6 7 t 
====================================================
 Power On Reset
0001: C X X X X X L L L L L L L X
0002: C 1 1 0 0 H H H H H H H H Z
0003: C 1 1 0 0 H H H H H H H H Z
 Q0 - 0ws
0004: C 1 1 0 0 H H H H H H H H Z
0005: C 1 0 0 0 L H H H H H H H H
0006: C 1 0 0 0 L L H H H H H H H
0007: C 1 0 0 0 L L L H H H H H H
0008: C 1 0 0 0 L L L L H H H H H
0009: C 1 0 0 0 L L L L L H H H H
0010: C 1 0 0 0 L L L L L L H H H
0011: C 1 0 0 0 L L L L L L L H H
0012: C 1 0 0 0 L L L L L L L L H
0013: C 1 0 0 0 L L L L L L L L H
0014: C 1 1 0 0 H H H H H H H H Z
0015: C 1 1 0 0 H H H H H H H H Z
 Q2 - 2ws
0016: C 1 1 0 1 H H H H H H H H Z
0017: C 1 0 0 1 L H H H H H H H L
0018: C 1 0 0 1 L L H H H H H H L
0019: C 1 0 0 1 L L L H H H H H H
0020: C 1 0 0 1 L L L L H H H H H
0021: C 1 0 0 1 L L L L L H H H H
0022: C 1 0 0 1 L L L L L L H H H
0023: C 1 0 0 1 L L L L L L L H H
0024: C 1 0 0 1 L L L L L L L L H
0025: C 1 0 0 1 L L L L L L L L H
0026: C 1 1 0 1 H H H H H H H H Z
0027: C 1 1 0 1 H H H H H H H H Z
 Q4 - 4ws
0028: C 1 1 1 0 H H H H H H H H Z
0029: C 1 0 1 0 L H H H H H H H L
0030: C 1 0 1 0 L L H H H H H H L
0031: C 1 0 1 0 L L L H H H H H L
0032: C 1 0 1 0 L L L L H H H H H
0033: C 1 0 1 0 L L L L L H H H H
0034: C 1 0 1 0 L L L L L L H H H
0035: C 1 0 1 0 L L L L L L L H H
0036: C 1 0 1 0 L L L L L L L L H
0037: C 1 0 1 0 L L L L L L L L H
0038: C 1 1 1 0 H H H H H H H H Z
0039: C 1 1 1 0 H H H H H H H H Z
 Q7 - 7ws
0040: C 1 1 1 1 H H H H H H H H Z
0041: C 1 0 1 1 L H H H H H H H L
0042: C 1 0 1 1 L L H H H H H H L
0043: C 1 0 1 1 L L L H H H H H L
0044: C 1 0 1 1 L L L L H H H H L
0045: C 1 0 1 1 L L L L L H H H L
0046: C 1 0 1 1 L L L L L L H H L
0047: C 1 0 1 1 L L L L L L L H L
0048: C 1 0 1 1 L L L L L L L L H
0049: C 1 0 1 1 L L L L L L L L H
0050: C 1 1 1 1 H H H H H H H H Z
0051: C 1 1 1 1 H H H H H H H H Z

 

 

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s