I've been plugging away at the logic for my POC V2 computer and have been stumbling over what turns out to be a problem with Atmel's WinCUPL development software. First, here's the code I'm working with, then I'll explain the booby-trap:
Code:
/*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* *
* PROOF-OF-CONCEPT V2 LOGIC *
* *
* --------------------------------------------------------------------------- *
* *
* Copyright (C)2010 by BCS Technology Limited. All rights reserved. *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* * * * * * * * * *
* VERSION HISTORY *
* * * * * * * * * *
Ver Rev Date Revision
------------------------------------------------------------------------------
01 2010/11/04 Original version.
02 2010/12/06 Changed device, added wait-state features & memory banking, &
removed PHI2 generation.
------------------------------------------------------------------------------
*/
Name mpu_logic;
PartNo B011040001;
Date 11/04/2010;
Revision 02;
Designer BigDumbDinosaur;
Company BCS Technology Limited;
Assembly POC V2;
Location Ux;
Device v2500clcc;
/*
* * * * * * * * * * * *
* INPUT DECLARATIONS *
* * * * * * * * * * * *
*/
pin 42 = !EWS; /* add a wait-state if low */
pin 1 = PHI2; /* MPU clock */
pin 19 = RESET; /* system reset if low */
pin 44 = RWB; /* MPU read/write signal */
pin 2 = VDA; /* MPU valid data address signal */
pin 3 = VPA; /* MPU valid program address signal */
/* MPU address lines... */
pin 25 = A8;
pin 24 = A9;
pin 43 = A10;
pin 41 = A11;
pin 23 = A12;
pin 22 = A13;
pin 20 = A14;
pin 21 = A15;
/* MPU data lines... */
pin 6 = D0;
pin 5 = D1;
pin 8 = D2;
pin 16 = D6;
pin 17 = D7;
/*
* * * * * * * * * * * *
* OUTPUT DECLARATIONS *
* * * * * * * * * * * *
*/
pin 35 = !EPCE; /* EPROM chip select */
pin 36 = !SRCE; /* SRAM chip select */
pin 38 = !RD; /* inverted read data */
pin 40 = !RDY; /* MPU wait-state */
pin 18 = RST; /* active high reset */
pin 37 = !WD; /* write data gated by PHI2 */
/* RAM bank selection... */
pin 15 = A16;
pin 14 = A17;
pin 13 = A18;
/* I/O device selection... */
pin 29 = !IO0; /* I/O device chip select */
pin 30 = !IO1; /* I/O device chip select */
pin 31 = !IO2; /* I/O device chip select */
pin 32 = !IO3; /* I/O device chip select */
/*
* * * * * * * * * *
* HARDWARE NODES *
* * * * * * * * * *
*/
pin 7 = wd; /* write data node */
pin 9 = romsel; /* ROM selection */
pin 10 = ramsel; /* RAM selection */
pin 27 = romhi; /* HIROM selection */
pin 28 = romlo; /* LOROM selection */
/*
* * * * * * * * * * * *
* FIELD DECLARATIONS *
* * * * * * * * * * * *
*/
field ADR = [A15,A14,A13,A12]; /* RAM/ROM address range bits */
field IOB = [A11,A10,A9,A8]; /* I/O addresses */
field DAB = [D7,D6,D2,D1,D0]; /* significant part of data bus */
/*
* * * * * * * * *
* BURIED LOGIC *
* * * * * * * * *
*/
node d0ff; /* D0 state flip-flop */
node d1ff; /* D1 state flip-flop */
node d2ff; /* D2 state flip-flop */
node d6ff; /* D6 state flip-flop */
node d7ff; /* D7 state flip-flop */
node memmap; /* memory mapping */
node ws; /* wait-state enable */
node wsff1; /* wait-state flip-flop */
node wsff2; /* wait-state flip-flop */
node wsff3; /* wait-state flip-flop */
/*
* * * * * * * * *
* INTIALIZATION *
* * * * * * * * *
*/
d0ff.ar = !RESET;
d1ff.ar = !RESET;
d2ff.ar = !RESET;
d6ff.ar = !RESET;
d7ff.ar = !RESET;
wsff1.ar = !RESET;
wsff2.ar = !RESET;
wsff3.ar = !RESET;
d0ff.sp = 'b'0;
d1ff.sp = 'b'0;
d2ff.sp = 'b'0;
d6ff.sp = 'b'0;
d7ff.sp = 'b'0;
wsff1.sp = 'b'0;
wsff2.sp = 'b'0;
wsff3.sp = 'b'0;
/*
* * * * * * * * * * * * *
* CONTROL SIGNALS LOGIC *
* * * * * * * * * * * * *
*/
RST = !RESET; /* active high reset */
vbus = VDA # VPA; /* true if address bus is valid */
/*
* * * * * * * * * * *
* ADDRESSING LOGIC *
* * * * * * * * * * *
Memory Map Rules:
Address MMU RWB Hardware Symbol
--------------------------------------------------
$bb0000-$bbBFFF xx000bbb x banked RAM
$00C000-$00CFFF x000xxxx x common RAM LORAM
x100xxxx H ROM (4K) LOROM
x100xxxx L common RAM LORAM
$00D000-$00DEFF xx00xxxx x I/O IOBLK
$00DF00 xx00xxxx x MMU mmu
$00E000-$00FFFF 0x00xxxx H ROM (8K) HIROM
0x00xxxx L common RAM HIRAM
1x00xxxx x common RAM HIRAM
--------------------------------------------------
*/
loram = A15 & A14 & !A13 & !A12; /* RAM at $00C000 */
lorom = A15 & A14 & !A13 & !A12; /* ROM at $00C000 */
dxxx = A15 & A14 & !A13 & A12; /* $00D000 ... */
ioblk = dxxx & !A11; /* I/O at $00D000 */
mmu = dxxx & A11 & A10 & A9 & A8; /* memory mapping at $DF00 */
hiram = A15 & A14 & A13; /* RAM at $00E000 */
hirom = A15 & A14 & A13; /* ROM at $00E000 */
memmap = mmu & !RWB & vbus; /* 1 = configuring memory map */
d7ff.ck = memmap & PHI2;
d6ff.ck = memmap & PHI2;
d2ff.ck = memmap & PHI2;
d1ff.ck = memmap & PHI2;
d0ff.ck = memmap & PHI2;
d7ff.d = D7 & memmap;
d6ff.d = D6 & memmap;
d2ff.d = D2 & memmap;
d1ff.d = D1 & memmap;
d0ff.d = D0 & memmap;
vbank = !loram & !hiram & vbus;
A18 = d2ff & vbank;
A17 = d1ff & vbank;
A16 = d0ff & vbank;
/*
* * * * * * * * * * * *
* ROM SELECTION LOGIC *
* * * * * * * * * * * *
*/
romhi = hirom & !d7ff & RWB; /* high ROM enabled on read */
romlo = lorom & d6ff & RWB; /* low ROM enabled on read */
EPCE = (romhi # romlo) & vbus; /* ROM chip enable */
/*
* * * * * * * * * * * *
* RAM SELECTION LOGIC *
* * * * * * * * * * * *
*/
ramhi = (hiram & d7ff) #
(hiram & !RWB);
ramlo = (loram & !d6ff) #
(loram & !RWB);
SRCE = (ramhi # ramlo) & vbus; /* RAM chip enable */
/*
* * * * * * * * * * * *
* I/O SELECTION LOGIC *
* * * * * * * * * * * *
*/
iosel = ioblk & vbus; /* true if I/O device selected */
IO0 = iosel & !A10 & !A9 & !A8; /* I/O device 0 */
IO1 = iosel & !A10 & !A9 & A8; /* I/O device 1 */
IO2 = iosel & !A10 & A9 & !A8; /* I/O device 2 */
IO3 = iosel & !A10 & A9 & A8; /* I/O device 3 */
/*
* * * * * * * * * * *
* WAIT-STATE LOGIC *
* * * * * * * * * * *
*/
ws = EPCE # iosel; /* wait-state ROM or I/O access */
wsff1.ck = PHI2 & ws; /* enable flop clock for wait-state */
wsff1.d = (!wsff3 & EWS) # (!wsff2 & !EWS);
wsff2.d = wsff1;
wsff3.d = wsff2;
RDY.oe = ws; /* tri-state RDY when not active */
RDY = ws & (wsff1 $ ((wsff3 & EWS) #
(wsff2 & !EWS))); /* assert RDY if wait-stating */
/*
* * * * * * * * * * *
* READ/WRITE LOGIC *
* * * * * * * * * * *
*/
RD = (RWB # (RWB & RDY)) & vbus; /* read data operation */
wd = !RWB & !mmu; /* ignore RWB if accessing MMU */
WD = ((wd & PHI2) # (wd & RDY))
& vbus; /* write data operation */
Don't see anything wrong with the above? I didn't either, and technically speaking, it is 100 percent compliant with the CUPL standard. The above code compiles without any errors whatsoever. Yet, it cannot be simulated in WinSim due to an insidious bug.
When an attempt is made to simulate the above, WinSim croaks with a run-time error 457, which is a key indexing error that is emitted by Microsoft Visual Basic (now we know what Atmel's developers use
). Nothing I could do would allow me to create and save a simulation file, let alone actually run it.
After having puzzled over this one for quite a while, as well getting Daryl Rictor (8Bit) to try it out, we both reached the same conclusion and I queried Atmel on it. Here's Atmel's reply:
The WinSim issue seems to be caused by the use of “wd” and “WD” in the CUPL design file. I tried changing “WD” to “WD_t” and that fixed the WinSim problem.
Hope this will help you solve the problem. Please feel free to contact us at pld@atmel.com if you have any Atmel PLD related inquiries.
Best regards,
Alan Wong
CSP Applications Manager / Atmel Corporation
Tel: (+1) (408) 436-4156 / Fax: (+1) (408) 487-2538
The variables being referenced are used at the very end of the code.
WD is a pin and
wd is a node. CUPL says variables names are case-sensitive, so one should be able to do what I did without error. And, as I said, it will compile. It just won't simulate. So the workaround is to not use the same variable name twice, as it appears Visual Basic doesn't recognize the case difference.