I'm having issues attempting to get a ATF22V10CQZ to do my bidding. However, the source of the problem may be (at least) one of three things...
1) My lack of knowledge and understanding of what I think I'm attempting to do/the way I'm going about it,
2) An issue with Wincupl,
3) An issue with my verification process.
Using the address pins A15 to A5 inclusive, I am attempting to create the following memory map for my WDC65C02 system to use just one page for IO...
Code:
0000 - 7F00 RAM
7F00 - 7F1F IO0
7F20 - 7F3F IO1
7F40 - 7F5F IO2
7F60 - 7F7F IO3
7F80 - 7FFF IOX
8000 - FFFF ROM
I have the connections to the ATF22V10 as follows...
Code:
________
| |
CLK x---|1 24|---x Vcc
RW x---|2 23|---x IOX_CS
A15 x---|3 22|---x IO3_CS
A14 x---|4 21|---x IO2_CS
A13 x---|5 20|---x IO1_CS
A12 x---|6 19|---x IO0_CS
A11 x---|7 18|---x ROM_CS
A10 x---|8 17|---x RAM_CS
A9 x---|9 16|---x OE
A8 x---|10 15|---x WE
A7 x---|11 14|---x A5
GND x---|12 13|---x A6
|________|
I generate the .jed file from Wincupl with no warnings or errors and I program the device using my TL866II+ again with no errors. I've used "ATF22V10CQZ" as well as "ATF22V10CQZ(UES)" when programming using minipro.
However, when I hook the CPLD up to my Arduino to check the logic between the address pins and the chip selects, I get the following (I reproduce the output around 8000 where all the action should happen)...
Code:
AAAA AAAA AAA R R I I I I I
1111 1198 765 A O O O O O O
5432 10 M M 0 1 2 3 X
0111 1110 101 -> 0 1 1 1 1 1 1
0111 1110 110 -> 0 1 1 1 1 1 1
0111 1110 111 -> 0 1 1 1 1 1 1
0111 1111 000 -> 1 1 1 0 1 1 1
0111 1111 001 -> 1 1 1 0 1 1 1
0111 1111 010 -> 1 1 1 1 1 0 1
0111 1111 011 -> 1 1 1 1 1 0 1
0111 1111 100 -> 1 1 1 1 1 1 0
0111 1111 101 -> 1 1 1 1 1 1 0
0111 1111 110 -> 1 1 1 1 1 1 0
0111 1111 111 -> 1 1 1 1 1 1 0
1000 0000 000 -> 1 0 1 1 1 1 1
1000 0000 001 -> 1 0 1 1 1 1 1
1000 0000 010 -> 1 0 1 1 1 1 1
I really expected this, however...
Code:
AAAA AAAA AAA R R I I I I I
1111 1198 765 A O O O O O O
5432 10 M M 0 1 2 3 X
0111 1110 101 -> 0 1 1 1 1 1 1
0111 1110 110 -> 0 1 1 1 1 1 1
0111 1110 111 -> 0 1 1 1 1 1 1
0111 1111 000 -> 1 1 0 1 1 1 1
0111 1111 001 -> 1 1 1 0 1 1 1
0111 1111 010 -> 1 1 1 1 0 1 1
0111 1111 011 -> 1 1 1 1 1 0 1
0111 1111 100 -> 1 1 1 1 1 1 0
0111 1111 101 -> 1 1 1 1 1 1 0
0111 1111 110 -> 1 1 1 1 1 1 0
0111 1111 111 -> 1 1 1 1 1 1 0
1000 0000 000 -> 1 0 1 1 1 1 1
1000 0000 001 -> 1 0 1 1 1 1 1
1000 0000 010 -> 1 0 1 1 1 1 1
RAM, ROM and IOX behave as expected, but I am stumped as to why IO0 and IO2 never get selected whilst IO1 and IO3 are selected twice.
Why do 0111 1111 000 and 0111 1111 001 give the same output? (as does 0111 1111 010 and 0111 1111 011).
I have tried 3 different ways of inputting the logic into Wincupl (becoming more verbose each time) - they all pass with no errors and provide the same result when testing. Here is my latest offering...
Code:
Name 65C02GlueLogic ;
PartNo 00 ;
Date 13/08/2023 ;
Revision 00 ;
Designer DRG ;
Company ;
Assembly ;
Location ;
Device g22V10 ;
/* Input */
Pin 1 = CLK;
Pin 2 = RW;
Pin [3..11] = [A15..7];
Pin [13..14] = [A6..5];
/* Output */
Pin 15 = WE;
Pin 16 = OE;
Pin 17 = RAM_CS;
Pin 18 = ROM_CS;
Pin 19 = IO0_CS;
Pin 20 = IO1_CS;
Pin 21 = IO2_CS;
Pin 22 = IO3_CS;
Pin 23 = IOX_CS;
/* Local Variables */
ROM = A15;
IO = !A15 & A14 & A13 & A12 & A11 & A10 & A9 & A8; /* Temp variable */
IO0 = IO & !A7 & !A6 & !A5;
IO1 = IO & !A7 & !A6 & A5;
IO2 = IO & !A7 & A6 & !A5;
IO3 = IO & !A7 & A6 & A5;
IOX = IO & A7;
RAM = !(IO0 # IO1 # IO2 # IO3 #IOX # ROM);
!WE = CLK & !RW;
!OE = CLK & RW;
!RAM_CS = RAM;
!ROM_CS = ROM & RW;
!IO0_CS = IO0;
!IO1_CS = IO1;
!IO2_CS = IO2;
!IO3_CS = IO3;
!IOX_CS = IOX;
Previous to this, I used the following with the same pin definitions...
Code:
/* Local Variables */
FIELD Address = [A15..5];
FIELD Decodes = [RAM, !IO0_CS, !IO1_CS, !IO2_CS, !IO3_CS, !IOX_CS, ROM];
/* Logic */
TABLE Address => Decodes {
[0000..7EFF] => 'b'1000000;
[7F00..7F1F] => 'b'0100000;
[7F20..7F3F] => 'b'0010000;
[7F40..7F5F] => 'b'0001000;
[7F60..7F7F] => 'b'0000100;
[7F80..7FFF] => 'b'0000010;
[8000..FFFF] => 'b'0000001;
}
/* Logic */
RAM = Address:[0000..7EFF];
IO0 = Address:[7F00..7F1F];
IO1 = Address:[7F20..7F3F];
IO2 = Address:[7F40..7F5F];
IO3 = Address:[7F60..7F7F];
IOX = Address:[7F80..7FFF];
ROM = Address:[8000..FFFF];
!WE = CLK & !RW;
!OE = CLK & RW;
!RAM_CS = RAM;
!ROM_CS = ROM & RW;
As well as my first effort...
Code:
/* Logic */
RAM = Address:[0000..7EFF];
IO0 = Address:[7F00..7F1F];
IO1 = Address:[7F20..7F3F];
IO2 = Address:[7F40..7F5F];
IO3 = Address:[7F60..7F7F];
IOX = Address:[7F80..7FFF];
ROM = Address:[8000..FFFF];
!WE = CLK & !RW;
!OE = CLK & RW;
!RAM_CS = RAM;
!ROM_CS = ROM & RW;
!IO0_CS = IO0;
!IO1_CS = IO1;
!IO2_CS = IO2;
!IO3_CS = IO3;
!IOX_CS = IOX;
My thinking is that 11 bits (A15-A5) will allow 64k to be divided into 2048 "blocks" of 32 bytes. Hence, my use of FF00-FF1F, FF20-FF3F etc.
I'm hoping someone from the forum can shed some light onto this as I have done as much self-help as I am able, trawling this forum and Google but not coming up with anything that highlights the problem.
Thanks.
Dave