A one-page CPU: spec, HDL, emulator and macro assembler each in one page. Fits in XC9572 CPLD.
To make the experience fit your profile, pick a username and tell us what interests you.
We found and based on your interests.
The final change to OPC-1: we removed SEC, because we had to fix a bug in the verilog, and then the machine didn't fit the CPLD, so something had to go. No great problem though, because with our macro assembler we can have an SEC like this:
MACRO SEC()
lda.i 0x01
lxa
ENDMACRO
You can run an emulation of OPC-1 in your browser: see here for a trivial program, or here or here for longer programs. (It's an emulator without many features, because, of course, it fits on one page.)
Our next mini-adventure was to see about an OPC-2 - instead of an accumulator machine, how about a load-store machine? More registers, operations on registers, and the only memory accesses to be loads and stores.
Unfortunately, although we did manage to make a working machine, fitting in the CPLD and again with all sources on one page, it didn't turn out very satisfactory. The CPLD is so small we could only have two registers, and the address space shrunk again to just 10 bits. We could only afford load and store from one of the registers. We managed a conditional jump and a jump-and-link, so again one can manage subroutines. But there was so little room JAL takes two bytes even though the second byte contains no information.
The spec is here, and the in-browser emulator is here.
At this point we've run out of room in the CPLD, and it's time for a new project. Although we might come back to OPC-1 and get it running in a breadboard - so far we've been exploring with synthesis, simulation and emulation.
For one last gasp, we wrote an OPC-3, which is a simple-minded expansion of OPC-1 into a machine with 16 address and 16 bit data. We quite like word-addressed machines, so this is one of those: addresses are not bytes! There's no simple way to access bytes although of course you can always shift and mask. But a benefit of this size of machine is that a value, whether in register or memory or as an operand byte, is always big enough to specify a full address.
OPC-3 is a bit too big for our CPLD and a bit too simple to be impressive. The instructions have lots of unused bits. But it leads us to think of interesting directions for the next project.
Still fitting within the CPLD, and still keeping source, spec and emulator within 66 lines, we managed to add a feature: indirect addressing.
Having reduced the address space from 12 to 11 bits, so we could fit in the CPLD, it turns out we had spare logic capacity (but of course no spare flop capacity) and we also had one bit freed up in the instructions.
So now we have a 5 bit opcode field. We gain a load instruction - LDA - and the store instruction - STA - gains a second addressing mode. In both cases there's an extra level of indirection: the effective address is the value loaded from the address given in the instruction. Because the pointers are fetched using only an 8-bit address, this gives the machine a zero page, like the 6502.
We also gain a set carry instruction, SEC, hoping to make subtraction-by-addition a little easier, as we lack a subtract instruction. And we gained a little by squeezing the carry bit into the link register. We needed that - the design now uses 100% of the Function Blocks in the CPLD.
Here's the updated spec.
We made an update, adding a link register and three instructions, which give us subroutine capability. There's still no stack!
The cost of this update, in fitting in the CPLD, was one address bit, so we move down from a 12 bit address space to 11 bits.
JSR stores the current PC in the link register and the accumulator - the PC is 11 bits, the accumulator only 8, so we needed a 3 bit link register. RTS copies the link and accumulator into the PC. That's almost enough, but to save a return address we need access to the link register, so LXA exchanges the link register and the accumulator.
In fact here's the spec on the subject:
Our aim here was to see if we could fit a useful CPU on a CPLD. We chose the Xilinx 9572 because we've used it before, and there's a breadboard-friendly dev board for it.
At the same time we wanted to see if we could describe a CPU in one page.
The 6502 is nice and simple but is too large for a CPLD and too complex to be described in one page, so we started with that and threw out the stack pointer, the index registers, and almost all the instructions. We're left with an accumulator machine, and we kept just two flags: the carry and the zero.
The first cut has a fixed instruction format of two bytes, which allows for two addressing modes: eight instructions in direct mode with a 12 bit operand, and sixteen instructions in implied/immediate mode with just an 8 bit operand. So we get a 12 bit address space, and a 256 byte zero page. We get LDA, ADD, SUB, and AND with two addressing modes, and STA. NOT, JP, JPC, JPZ and SEC with just one addressing mode.
With this version, not only must stack management be manual, but also subroutines have to be managed manually, perhaps by using a Wheeler Jump. Maybe self-modifying code would be essential. It's certainly a fully capable CPU though.
At this stage we also had an assembler and an emulator, both written in Python. See GitHub.
Create an account to leave a comment. Already have an account? Log In.
Thank you for liking my little experiment ;)
I'm running your tests in https://github.com/revaldinho/opc/tree/master/opc1
It looks like one test is not there:
FileNotFoundError: [Errno 2] No such file or directory: 'ptrtest.s'
I like this but I can't follow the hardware setup.
The hardware is a mystery to me as I use VHDL and not Verilog.
I have lots of these Xilinx CPLDs. I am not sure if I have the small breakout that you have but I know I have may larger breakouts. I also have various packages and about 100 XC9636XL s. It would be an interesting challenge to see what could be done in a XC9536XL. I also have some Altera CPLDs like EPM240 EPM570 Cyclone II etc.
This is great. Giving up an address bit to add an instruction seems like a wonderful tradeoff. How would I get started with the CPLD?
Thanks! For the CPLD, you need a Xilinx programming dongle, which they call a "Platform Adapter" - $50 or so from China - and then the free download software from Xilinx, WebPack ISE.
There are cheaper alternatives like this -
http://www.ebay.com/itm/311775553890
It's an Altera version with a CPLD on a breakout and a programmer for under $10. With the Altera Version the breakout board can be powered by the programmer from the USB 5 Volt supply. Very convenient.
It's an Altera EPM240 which is much bigger than the Xilinx XC9572XL. It's also 5Volt tolerant like the Xilinx XC9572XL.
Also the Xilinx ISE (WEB) is a pain to install and register because of the complex process to get a registration key even though it's free.
The Altera IDE is called Quartus and installs easily.
The Xilinx ISE will drive you mad with warnings and errors when you start and has a complex system for constraints.
The Altera Quartus is much easier to use and has a pin configuration GUI instead of .ucf files.
I'm not putting the Xilinx ISE package down. It has advantages that I like as well so I use both Xilinx ISE and Altera Quartus. It's just that it's a pain in the ass to start with the Xilinx package first.
Altera is a good alternative - but it looks like the chip is only 5v tolerant if you add series resistors. Possibly the breakout board you linked will include those, although it doesn't look like does.
No, that breakout doesn't have series resistors but I have never had problems mixing the EPM240 or EPM570 with TTL devices. CMOS may be different.
The EPM datasheet assumes that the driving device can drive right up to it's Vcc which for TTL is max 5.5V but in reality modern circuits have a fairly accurate 5.0V supply and TTL Voh is below the EMP's Vih max of 4.0V
For my own designs I also run the 3.3V device at its max Vcc of 3.6V to improve noise margin but all the same I have used several EPM breakout boards from ebay directly with TTL devices and never had a problem.
I did however notice that the EPM has only 100 write cycles for the configuration and user flash and that was surprising.
The EPM is a lot more versatile. I has many options for the IO pins including PCI. There is also some small user FLASH built in.
Do you need 5V compatibility? The Altera Cyclone II chips give a lot better bang for buck than the aging EPM series.
The EMP240 is about 190 macro's compared to the Xilinx XC9572XL's 72 macro's.
This kit for about $16USD is about 3500 macro's but it's not 5V compatible at all.
http://www.ebay.com/itm/162595684147
Still it's a cheap way to cut your teeth with VHDL/Verilog/Schematic entry.
Become a member to follow this project and never miss any updates
By using our website and services, you expressly agree to the placement of our performance, functionality, and advertising cookies. Learn More
I think OPC soft-cores could be perfect lab rats for my C++HDL project https://hackaday.io/project/160393-trcm :)