Micro8 A very simple VHDL microprocessor
Micro8.zip Original Micro8 design.
This design has some problems. Not all control signals are resolved in each state which makes the synthesis tools kick up a few warnings.
Micro8-1.gif Architecture Diagram 1
Micro8-2.gif Architecture Diagram 2
Micro8-2003-05-21.zip New improved version
This design has a number of modifications. Firstly it is now wishbone compliant (I think). It uses a wishbone version of MiniUART by Philippe CARTON which can be found on the open cores web site.
I've:
fixed the data output Mux and resolved the ALU control in some of the CPU states. made some changes to the adder inputs on the PC and EA registers. hidden the execute cycle behind the fetch cycle, so it saves one idle bus cycle. added a hold control on the cpu to stretch memory accesses on slow wishbone devices. added a Wishbone compliant UART
Doug Hodson has a version of Micro8 for his Xess XSA100 FPGA board.
Check out his project page on his RETRO MICRO page.
Micro8VDU-2003-05-24.zip Micro8 now has a Video Display Unit
This version has a built it Video Display Unit and a 64 byte ROM containing a very basic video terminal driver. Its not perfect by any stretch of the imagination. There are a few issues with the reliability of accessing SRAM on the Burch ED FPGA board. The video generator was based on the video timing logic on Doug Hodson's RETRO MICRO web site. The original design worked at 25 MHz, but I did not think Micro8 would run faster enough for the VDU to synchronously interleave memory accesses with the CPU. I run Micro 8 and the VDU at 9.8 MHz. Scaling the display, this gives 32 characters across rather than 80. I'm sure I could run a slower horizontal sync rate though, and increase the characters on the display. Timing constraints indicate Micro 8 should run at 20 MHz, however 25MHz might be pushing it.
Basically what happens in this design is that if the VDU wants memory access, it has priority over the CPU. Normally the CPU is accessing ROM or I/O and won't be affected by the VDU accessing RAM, but if there is a collision, I delay the acknowledge strobe back to the CPU, effectively stretch the RAM access until the VDU has finished. The character generator ROM is 1K byte long. it has 128 characters, each character occupying 8 rows. The 8 data bits are shifted out the video connector.
The VDU has four registers....
00 - Data Register (Character to be output)
01 - Character Colour (Colour of character (BI, BB, BG, BR, FI, FB, FG, FR))
10 - Horizontal Cursor position ( 0-31 columns of characters)
11 - Vertical Cursor position (0-29 rows of characters)
All registers are read/writeable.
where:
B = Background,
F= Foreground,
I=Intensity,
B=Blue,
G= Green,
R=Red
the 64 byte video driver
clears the current line,
polls the UART for a character,
echo's the character to the UART,
outputs the character to the display,
if the character is a Carraige Return (Enter)
the Cursor is incremented down the screen and the new line is cleared,
other wise the horizontal cursor is incremented
if we reach the end of the line,
the vertical cursor posotion is also incremented and a new line started
The baud rate of the UART at 9.8 MHz is 19K2 Baud.
Introduction
Micro8 started of as a minimal set 4 instruction computer By Tim Boscke designed to fit in a 32 Macrocell CPLD.
http://www.tu-harburg.de/~setb0209/cpu/
I've added to it considerably and run it on the B3-Spartan2+ board with the B3-CPU-IO interface board. The complete CPU and miniUART use about 12% of a XC2S200 or 23% of a XC2S100. Note that although I have included the add on SRAM in the I/O pinouts, it does not use the SRAM to print the message, the code should run quite happily without the SRAM module. I put the I/O interface module on connector J3 of the B3 board, but its probably better suited to J8.
Tim's computer had the following instructions ADD, NOR , STA and JCC. It had a single carry bit which was reset by the JCC (Jump on Carry) instruction. Most microprocessor instructions can be built up using these basic instructions.
7
6
5
4
3
2
1
0
Register
Instruction
addressing mode
address hi / offset hi
7
6
5
4
3
2
1
0
addr lo / offset lo / 8 bit immediate value
I have extended the instruction set by:
Bit 7 selects between accumulator or index register instructions
- Adding an 8 bit index register.
B7 - Register
0 - A - Accumulator
1 - X - Index Register
B6, B5 - Instruction bits
- The four instructions remain much the same
00 - ADD - add memory to register
01 - NOR - nor register with memory
10 - STO - Store register to memory
11 - Bcc - Branch on condition code
Tim's computer only had absolute addressing
- I Added 4 addressing modes:
B4, B3 - Addressing mode bits
00 - I - Immediate (8 bit value)
01 - A - Absolute (11 bit address)
10 - X - Indexed (11 bit offset)
11 - P - PC Relative (11 bit offset)
In Tim's computer, there was only one carry bit which was reset by the jump. This was so that subsequent jump instructions where always takem. The jump instruction also used absolute addressing. On my version, only ADD, NOR and STO affect the condtion codes, not the branches. The branch instructions on my computer have a 11 bit displacements so can jump anywhere in the address range. It would be nice to have an absolute JMP instruction, to jump to fixed locations but there is not enough room in the opcode map.
- Added 8 conditional branch instructions (PC relative)
B7, B6, B5, B4, B3
01100 - BRA - Branch Always
01101 - BEQ - Branch if Zero flag set
01110 - BCS - Branch carry flag set
01111 - BMI - Branch if Negative flag set (Negative)
11100 - BRN - Branch never
11101 - BNE - Branch if not Zero
11110 - BCC - Branch carry clear
11111 - BPL - Branch if Negative flag Clear (Positive)
The high address is formed by Bit B2, B1 and B0 of the opcode and the low order address or immediate value by B7 to B0 of the second byte. This means you can address 2K bytes of memory, where as Tim's computer could only address 6 bits or 64 bytes of memory.
- Instructions are now all 2 bytes long.
Instruction Macros
To Clear a register,
NORAI #FF
To Load a register from memory
NORAI #FF
ADDAA address
To perform ones compliment
NORAI #00
To test a bit, say bit 0
NORAI #FE ; set all other bits and invert
BEQ branch_address ; test for opposite state
I have not tested all the instructions but the code prints out "Hello World" on the miniuart and waits for a character to be entered. Note that the system was tested with a 4.915 MHz clock, so you either have to set the jumpers of the ICST525-01 accordingly or hack the miniUART code. The Wishbone MiniUart operates at 9600 baud given a 4.915 MHz clock input. The default baudate divider was 130 for a 5MHz clock, however I have modified it to 128 for a 4.915 MHz clock.