CPLD + 6502 Trainer
CPLD + 6502 Trainer
I have boards for JLCPCB before the Chinese New Year break. Reading about Chad Burrow's experience with CPLD motivated me to think about a CPLD+6502 trainer for the 6502 community. I couldn't find CPLD trainer online with 6502 so I thought I throw something together quickly and send it in with rest of my order.
One of the interesting aspect of CPLD design is that pc board can be designed and fabricated first before CPLD design is completed. This does not work every time, but well enough to risk the $4 pcb fabrication run. So here is rev0 of CPLD+6502 Trainer.
* EPM7128SLC84 5V CPLD
* 6502 or 65816 CPU
* 512K RAM
* 512K EPROM
* Six 7-segment displays
* Serial port
* PS2 port
* I2C port
* RC6502 Expansion
* Single-step button
* Economical 4"x4" 2-layer Through-hole design
* PacTec CM5-125 enclosure
All features above cannot be implemented at the same time. CPLD is reprogrammed for the desired feature set. It is unlikely all features will work the first time so the immediate goal is to get the board running and find out what works. Ultimately the trainer is designed for the following list of goals (partial list):
* Blink 7-segment display
* NOP tester for 6502
* Glue logic for 6502 SBC
* Bootstrap 6502 using CPLD
* Single Step 6502 execution
* Add serial port in CPLD
* EPROM programmer
* Exploring I2C capability
* Driving WS2812B LED array
* 65816 with 512K RAM and 512K EPROM
* Add PS2 keyboard capability
* VGA capability via RC6502 expansion bus
* Standalone 6502/65816 computer
Yep, these are ambitious goals and probably won't all be realized with the first board. More reasons to get on with it.
Bill
One of the interesting aspect of CPLD design is that pc board can be designed and fabricated first before CPLD design is completed. This does not work every time, but well enough to risk the $4 pcb fabrication run. So here is rev0 of CPLD+6502 Trainer.
* EPM7128SLC84 5V CPLD
* 6502 or 65816 CPU
* 512K RAM
* 512K EPROM
* Six 7-segment displays
* Serial port
* PS2 port
* I2C port
* RC6502 Expansion
* Single-step button
* Economical 4"x4" 2-layer Through-hole design
* PacTec CM5-125 enclosure
All features above cannot be implemented at the same time. CPLD is reprogrammed for the desired feature set. It is unlikely all features will work the first time so the immediate goal is to get the board running and find out what works. Ultimately the trainer is designed for the following list of goals (partial list):
* Blink 7-segment display
* NOP tester for 6502
* Glue logic for 6502 SBC
* Bootstrap 6502 using CPLD
* Single Step 6502 execution
* Add serial port in CPLD
* EPROM programmer
* Exploring I2C capability
* Driving WS2812B LED array
* 65816 with 512K RAM and 512K EPROM
* Add PS2 keyboard capability
* VGA capability via RC6502 expansion bus
* Standalone 6502/65816 computer
Yep, these are ambitious goals and probably won't all be realized with the first board. More reasons to get on with it.
Bill
- Attachments
-
- Trainer+6502_scm.pdf
- (34.9 KiB) Downloaded 220 times
Re: CPLD + 6502 Trainer
Looks interesting, sign me up as a guinea pig!
Edit: I mean alpha-beta tester!!
Edit: I mean alpha-beta tester!!
Re: CPLD + 6502 Trainer
OK, I'll mail you a blank board once I've checked it will work with 6502.
Bill
Bill
Re: CPLD + 6502 Trainer
Nice! It'll be very interesting to see how this develops.
Re: CPLD + 6502 Trainer
I'd like to give it shot too, of course.
I like the fact that you can do many things with it, without having to use the 6502 necessarily (at least that's what I got from your description). I also like the all in one experience, and the ability for expansion. I've got the 7128S coming in the mail, and already have the PLCC84 sockets.
Thanks Bill, looks great!
Chad
Thanks Bill, looks great!
Chad
Re: CPLD + 6502 Trainer
Chad,
OK, saving one board for you.
I have 5 boards fabricated. Saving 2 for me, 2 for forum members, and one more available to give away.
I should have the boards next week. I'm working on a lesson plan that looks like this:
1. populate the bare minimal and do a CPLD check
2. Populate one 7-seg display and drive it with CPLD
3. Populate all 7-seg displays and drive it with 20-bit counter
4. Populate 6502 and do NOP test, show address/data with 7-seg displays
5. Install single-step switch and show 6502 single stepping
6. Add serial port, add serial transmitter in CPLD.
7. Write program in CPLD to send data out of serial transmitter
8. Add RAM and EPROM and glue logic in CPLD and run simple boot program in EPROM
9. Demonstrate a working SBC
If board is working up to this point then:
* Exploring W65C816 option
* Exploring EPROM programmer
* Exploring PS2 keyboard
* Exploring I2C with 128x64 OLED display
* Exploring WS2812B LED array
* Exploring RC6502 expansion connector with graphic card
* Ultimate goal of a standalone 6502/65816 computer with PS2 keyboard and VGA graphic
Reminds me of "lie, damned lies, and projection"
Bill
OK, saving one board for you.
I have 5 boards fabricated. Saving 2 for me, 2 for forum members, and one more available to give away.
I should have the boards next week. I'm working on a lesson plan that looks like this:
1. populate the bare minimal and do a CPLD check
2. Populate one 7-seg display and drive it with CPLD
3. Populate all 7-seg displays and drive it with 20-bit counter
4. Populate 6502 and do NOP test, show address/data with 7-seg displays
5. Install single-step switch and show 6502 single stepping
6. Add serial port, add serial transmitter in CPLD.
7. Write program in CPLD to send data out of serial transmitter
8. Add RAM and EPROM and glue logic in CPLD and run simple boot program in EPROM
9. Demonstrate a working SBC
If board is working up to this point then:
* Exploring W65C816 option
* Exploring EPROM programmer
* Exploring PS2 keyboard
* Exploring I2C with 128x64 OLED display
* Exploring WS2812B LED array
* Exploring RC6502 expansion connector with graphic card
* Ultimate goal of a standalone 6502/65816 computer with PS2 keyboard and VGA graphic
Reminds me of "lie, damned lies, and projection"
Bill
Re: CPLD + 6502 Trainer
Received the board today. First step is to popular the bare minimal components needed to perform initial check out. The bare minimal because it is easier to troubleshoot if something is not working. So the bare minimum are
* Power circuit and reset supervisor
* CPLD programming header
* CPLD socket
* 7-segment display and associated drivers.
CPLD pins must be assigned according to the schematic.
The first test is to make sure CPLD can be programmed which is an important test because many used CPLD have been "locked" and can be unlocked only with special programmer that is nearly impossible to find. My batch of CPLD has been previously programmed OK, so if it has problem with programming on this board, the problem is most likely in the programming header connections.
First test is just to turn on the 7-segment display. And it works. Good, this means the CPLD can be programmed, the programming header connection is good, the pin assignments of the CPLD are correct, and the 7-segment display logic are good.
Bill
* Power circuit and reset supervisor
* CPLD programming header
* CPLD socket
* 7-segment display and associated drivers.
CPLD pins must be assigned according to the schematic.
The first test is to make sure CPLD can be programmed which is an important test because many used CPLD have been "locked" and can be unlocked only with special programmer that is nearly impossible to find. My batch of CPLD has been previously programmed OK, so if it has problem with programming on this board, the problem is most likely in the programming header connections.
First test is just to turn on the 7-segment display. And it works. Good, this means the CPLD can be programmed, the programming header connection is good, the pin assignments of the CPLD are correct, and the 7-segment display logic are good.
Bill
- Attachments
-
- CPLD_1st_test_scm.pdf
- (12.93 KiB) Downloaded 193 times
Re: CPLD + 6502 Trainer
Populate the rest of the 7-segment display and now I want to show activities on the display. To save number of wires, the six 7-segment displays are not directly driven by the CPLD, instead it is multipexed which is a very common way of driving array of 7-segment displays. These 7-segment displays are common cathode, i.e., the cathodes of the LEDs on a display all go to a common pin. By briefly connecting the common cathode to ground and driving the LED segments with corresponding values, the particular 7-segment display will briefly display the desired value. By rapidly turning on the common cathode of each 7-segment display in rapid succession and providing the corresponding values on the segment LED lines, multi-digit values can be displayed by taking advantage of persistence-of-vision with our eyes.
To illustrate the above and also checking the segment lines are correctly hookup, this is a simple circuit that divides the 7.37MHz clock to about 7Hz and drive a one-hot circular shift register. A one-hot circular shift register is a shift register with its last output connected to its first input with one register initialized to '1' while the rest of the registers are '0'. The outputs of the 6-stage one-hot circular shift register drive the common cathodes of the six 7-seg display so only one display is turned on at a time. The segment LED are wired so display 1 shows segment A, B; display 2 shows segment C; display 3 shows segment D; display 4 shows segment E; display 5 shows segment F; and display 6 shows segment G and decimal point. This will happen at 7Hz rate.
Bill
To illustrate the above and also checking the segment lines are correctly hookup, this is a simple circuit that divides the 7.37MHz clock to about 7Hz and drive a one-hot circular shift register. A one-hot circular shift register is a shift register with its last output connected to its first input with one register initialized to '1' while the rest of the registers are '0'. The outputs of the 6-stage one-hot circular shift register drive the common cathodes of the six 7-seg display so only one display is turned on at a time. The segment LED are wired so display 1 shows segment A, B; display 2 shows segment C; display 3 shows segment D; display 4 shows segment E; display 5 shows segment F; and display 6 shows segment G and decimal point. This will happen at 7Hz rate.
Bill
- Attachments
-
- 7hz_7-seg_display_drive.pdf
- (14.56 KiB) Downloaded 224 times
-
- 7hz_7-seg_display.gif (1.55 MiB) Viewed 20702 times
Re: CPLD + 6502 Trainer
Moving right along I see! That's a neat way of displaying multiple digits and yet keeping pins to a minimum. Never thought of that!
Chad
Chad
Re: CPLD + 6502 Trainer
Speeding up the rate of multiplexing by 1000 times will create a solid 6-digit display to our eyes. So instead of slowing down the 7.37MHz clock to 7Hz, it is divided by 1024 to about 7KHz and drive the one-hot circular shift registers.
Now lets create a 6-digit hexadecimal counter counting up: First I created a 24-bit counter (Cnt16M) driven by the same 7KHz that drives the one-hot shift registers. The same outputs of the shift registers that enable one 7-seg display at a time is also used to select one of the 6 nibbles of the 24-bit counter. The selected nibble is feed to TTL logic 7448, BCD to 7-segment decoder. Output of the 7448 drives the 7-segment display. The attached animated GIF shows the 6-digit counter counting.
You may notice that hex value $A/B/C/D/E/F are not displaying correctly. This is because 7448 does not generate the correct patterns for values greater than 9. This can be fixed by using a lookup table but lookup table is such useful concept that I want to talk about it in a separate session.
Bill
Now lets create a 6-digit hexadecimal counter counting up: First I created a 24-bit counter (Cnt16M) driven by the same 7KHz that drives the one-hot shift registers. The same outputs of the shift registers that enable one 7-seg display at a time is also used to select one of the 6 nibbles of the 24-bit counter. The selected nibble is feed to TTL logic 7448, BCD to 7-segment decoder. Output of the 7448 drives the 7-segment display. The attached animated GIF shows the 6-digit counter counting.
You may notice that hex value $A/B/C/D/E/F are not displaying correctly. This is because 7448 does not generate the correct patterns for values greater than 9. This can be fixed by using a lookup table but lookup table is such useful concept that I want to talk about it in a separate session.
Bill
- Attachments
-
- 6-digit-counter.pdf
- (16.85 KiB) Downloaded 186 times
-
- 6-digit-counter.gif (2.46 MiB) Viewed 20645 times
Re: CPLD + 6502 Trainer
Previously I've mentioned that TTL logic 7448 does not generate the correct patterns for input values greater than 9. To correct that, a lookup table can be generated to replace 7448. I want to talk about the lookup table in general because it can also serve as a small ROM for 6502.
Lookup table is purely combinatorial logic so in theory it takes no CPLD macrocell resource especially when it is a small lookup table. There are several ways of generating lookup table; it is certainly possible to do it in schematic with AND and OR gates, but that's way too tedious. Quartus can compile Verilog, and VHDL, so I'm generating the lookup table using Verilog.
In Quartus menu bar: File -> Create/Update -> Create Symbol Files for Current File to create a schematic symbol for the Verilog file. Then replace 7448 with the Verilog file symbol and re-compile.
You can see (third digit from the left) that hexadecimal values A/B/C/D/E/F are displayed correctly.
Next session I'll plug in a 6502 and use the 7-segment display capability to show address/data activities.
Bill
Lookup table is purely combinatorial logic so in theory it takes no CPLD macrocell resource especially when it is a small lookup table. There are several ways of generating lookup table; it is certainly possible to do it in schematic with AND and OR gates, but that's way too tedious. Quartus can compile Verilog, and VHDL, so I'm generating the lookup table using Verilog.
Code: Select all
module hex27seg(
input [3:0]bcd,
output reg [6:0]seg);
always @(*)
begin
//segment g,f,e,d,c,b,a correspond to seg[6] to seg[0]
//segment placement of 7-segment display
// -a-
// f| |b
// -g-
// e| |c
// -d-
case(bcd)
// gfedcba
4'b0000: seg = 7'b0111111; // "0"
4'b0001: seg = 7'b0110000; // "1"
4'b0010: seg = 7'b1011011; // "2"
4'b0011: seg = 7'b1001111; // "3"
4'b0100: seg = 7'b1100110; // "4"
4'b0101: seg = 7'b1101101; // "5"
4'b0110: seg = 7'b1111101; // "6"
4'b0111: seg = 7'b0000111; // "7"
4'b1000: seg = 7'b1111111; // "8"
4'b1001: seg = 7'b1101111; // "9"
4'b1010: seg = 7'b1110111; // "a"
4'b1011: seg = 7'b1111100; // "b"
4'b1100: seg = 7'b0111001; // "c"
4'b1101: seg = 7'b1011110; // "d"
4'b1110: seg = 7'b1111001; // "e"
4'b1111: seg = 7'b1110001; // "f"
endcase
end
endmodule
You can see (third digit from the left) that hexadecimal values A/B/C/D/E/F are displayed correctly.
Next session I'll plug in a 6502 and use the 7-segment display capability to show address/data activities.
Bill
- Attachments
-
- top_6-digit_hex_counter.pdf
- (16.23 KiB) Downloaded 169 times
-
- 7seg_hex_counter.gif (2.98 MiB) Viewed 20604 times
Re: CPLD + 6502 Trainer
Now is the time to plug in the 6502. 6502's address, data, read/write, ready, clock, interrupt, reset are all wired into CPLD so CPLD can decode the addresses, supply data, and observe the activities of 6502 easily.
The first test is the NOP test where CPLD drives the data bus with NOP instruction ($EA) and observes the address and data buses activities via six 7-segment displays. The group of 4 displays on the left side represents the address buses; the group of two on the right is data buses.
I did the NOP test first with 7.37MHz clock and everything is just a blur. Not surprising because 6502 executes a NOP in 2 clocks so it will execute through all 64K NOP instructions in 128K clocks. With 7.37MHz clock the 4-digit address displays will roll over 60 times a second. In order to see the program executing, a 10-bit counter (1024 counts) is connected to 6502's RDY to slow down 6502 by a factor of 1024. Now I can see the NOP instruction executing. This test also checked out most connections between CPLD and 6502 so we'll do something more challenging next session.
Bill
The first test is the NOP test where CPLD drives the data bus with NOP instruction ($EA) and observes the address and data buses activities via six 7-segment displays. The group of 4 displays on the left side represents the address buses; the group of two on the right is data buses.
I did the NOP test first with 7.37MHz clock and everything is just a blur. Not surprising because 6502 executes a NOP in 2 clocks so it will execute through all 64K NOP instructions in 128K clocks. With 7.37MHz clock the 4-digit address displays will roll over 60 times a second. In order to see the program executing, a 10-bit counter (1024 counts) is connected to 6502's RDY to slow down 6502 by a factor of 1024. Now I can see the NOP instruction executing. This test also checked out most connections between CPLD and 6502 so we'll do something more challenging next session.
Bill
- Attachments
-
- 6502 NOP test_CPLD schematic.pdf
- (16.72 KiB) Downloaded 187 times
-
- NOP test.gif (2.42 MiB) Viewed 20562 times
Re: CPLD + 6502 Trainer
NOP test is easy to do and really don't need a CPLD, just 8 resistors and a clock source. A CPLD can assists a processor to perform more complex tests without having EPROM, RAM or I/O. In today's post the 6502 will do more complex test with a small ROM program in CPLD and a simple serial transmitter to put data out on a terminal emulator.
The hex-to-7-segment lookup table described previously can be considered as a ROM where inputs are addresses and outputs are data. Here is a small program that transmit the content of regA to a terminal continuously:
This small bit of program is executed as soon as 6502 comes out of reset. The content of regs A, X, Y are unknown. X and Y are initialized to zeros before first regA content is transmitted. X and Y serve as delay between every transmit of reg A. Reg A is incremented every pass. Putting the above program in a lookup table below. It so happens that program is 12 bytes, plus the 4 bytes for reset and interrupt vector fit nicely in a 16-byte lookup table.
The serial transmitter is located at $E400. It is basically a TTL 74165 parallel-in serial-out shift register with few more logic to implement serial protocol's START bit circuitry. A divided-by-64 counter reduces the 7.37MHz system clock to 115200 baud. When "STA $E400" instruction writes to the serial port, the divided-by-64 counter is reset, 74165 is loaded with a byte of data, and the START bit register is reset to 0. Transmitter starts after the negation of the write.
The attached schematic show the entire circuitry including ROM, 7-segment display, and transmitter. A screen capture of the transmitter output is attached. This is a simple example of ROM program in CPLD. A larger CPLD ROM program can load data into RAM via serial port and program a EPROM without having a programmed EPROM in the first place. I'll describe such EPROM programmer later. The take away is CPLD + CPU can do many things
Bill
The hex-to-7-segment lookup table described previously can be considered as a ROM where inputs are addresses and outputs are data. Here is a small program that transmit the content of regA to a terminal continuously:
Code: Select all
.org $fff0
DEX ;delay, inner loop
BNE $fff0
DEY ;more delay, outer loop
BNE $fff0
STA $e400 ;write to transmitter
INC
BRA $fff0 ;repeat
.org $fffc ;reset vector
.word $fff0Code: Select all
module CPLD_ROM(
input [3:0]A,
output reg [7:0]Dout);
always @(*)
begin
//Boot ROM in CPLD
case(A)
4'b0000: Dout = 8'hCA; // DEX
4'b0001: Dout = 8'hD0; // BNE
4'b0010: Dout = 8'hFD; //
4'b0011: Dout = 8'h88; // DEY
4'b0100: Dout = 8'hD0; // BNE
4'b0101: Dout = 8'hFA; //
4'b0110: Dout = 8'h8D; // STA
4'b0111: Dout = 8'h00; //
4'b1000: Dout = 8'hE4; //
4'b1001: Dout = 8'h1A; // INC
4'b1010: Dout = 8'h80; // BRA
4'b1011: Dout = 8'hF4; //
4'b1100: Dout = 8'hF0; // RST vector
4'b1101: Dout = 8'hFF; //
4'b1110: Dout = 8'h00; //
4'b1111: Dout = 8'h00; //
endcase
end
endmoduleBill
- Attachments
-
- CPLD_ROM+SimpleTX.pdf
- (19.46 KiB) Downloaded 207 times
Re: CPLD + 6502 Trainer
Enough of booting out of CPLD, today I will add RAM and EPROM to the board. Below is a simple decode logic for RAM, EPROM, and expansion I/O such that
* EPROM is $F000-$FFFF
* Expansion I/O is $E800-$EFFF <-- Expansion I/O is for devices on RC6502 connector
* Internal (CPLD) I/O is $E000-$E7FF
- Simple Transmitter is still located at $E400
* RAM is $0-$DFFF
I will test the external EPROM with the same CPLD program of the previous post. So I copied the same 16-byte binary from the previous post and manually fill it in the TL866II and programmed a SST39SF010.
In CPLD design the internal ROM is removed, the RAM/EPROM/Expansion decodes are added, and the Simple Transmitter is retained. The CPLD design is attached below.
Turn on the power, and we got the same display. So moving ROM code from internal CPLD ROM to external EPROM produced the same result, as expected. We'll test the RAM next time.
Bill
* EPROM is $F000-$FFFF
* Expansion I/O is $E800-$EFFF <-- Expansion I/O is for devices on RC6502 connector
* Internal (CPLD) I/O is $E000-$E7FF
- Simple Transmitter is still located at $E400
* RAM is $0-$DFFF
I will test the external EPROM with the same CPLD program of the previous post. So I copied the same 16-byte binary from the previous post and manually fill it in the TL866II and programmed a SST39SF010.
In CPLD design the internal ROM is removed, the RAM/EPROM/Expansion decodes are added, and the Simple Transmitter is retained. The CPLD design is attached below.
Turn on the power, and we got the same display. So moving ROM code from internal CPLD ROM to external EPROM produced the same result, as expected. We'll test the RAM next time.
Bill
- Attachments
-
- EPROM_RAM_SimpleTX_schematic.pdf
- (20.61 KiB) Downloaded 201 times
Re: CPLD + 6502 Trainer
Progressing nicely, the step by step approach is instructive as you build on what works and rewrite what is required in the new stage.
Thanks Bill
Thanks Bill