View this PageEdit this PageLock this PageLinks to this PageUploads to this PageHistory of this PageHomeRecent ChangesSearchHelp Guide

hardware platform

The hardware platform is an expanded version of the design for the Oliver truck terminal. It includes:
  • a MISC style processor using a Xilinx Spartan II XC2S15 programmable chip
  • a 256 K by 16 Flash memory
  • a Xilinx CPLD XC9536 chip to allow the Spartan II to be loaded from the parallel Flash memory
  • a 4 M by 16 SDRAM chip
When data is being loaded into the FPGA the Flash is configured as 8 bits wide in order not to waste half of the first 20 K.

In addition to the data stack and return stack used in all other MISC (minimum instruction set computer) processors, the return stack also stores the value of the "self register". The processor has 16 bit wide data paths, but virtual addresses for memory are two groups of 16 bits: the object number (normally from the self register) and the field number (either from register A, R or the PC). The memory controller includes a virtually addressed cache. On a cache miss, a 32 bit physical address is generated and four words are transferred to/from main memory.

Instructions in memory are also 16 bits wide. When the top bit is 1, the bottom 15 bits indicate the value to be loaded into the PC for a send instruction. When the top bit is 0, then the bottom 15 bits form three groups of 5 bit primitive instructions.

These are the primitive instructions which are present in other MISC chips (see http://www.ultratechnology.com/chips.htm):

code instruction details
00000 jmp execution continues at the indicated address
00001 if like jmp, but only if the top of data stack is zero
00010 call like jmp, but saves current instruction pointer on the return stack
00011 -if like jmp, but only if the top of data stack is not zero
00110 return load top of return stack into instruction pointer
01000 @r+ load memory word addressed by the top of return stack and then increments the pointer
01001 @+ load memory word addressed by A and then increments A
01010 literal indicated bits are pushed onto the data stack
01011 @ load memory word addressed by A
01100 !r+ store into memory word addressed by the top of return stack and then increments the pointer
01101 !+ store into memory word addressed by A and increments A
01111 ! store into memory word addressed by A
10000 - invert all bits of top of stack (one's complement)
10001 2* shift left TOS by one bit
10010 2/ shift right TOS by one bit with sign extension
10011 +* add top elements of data stack, but only if lowest bit of TOS is one (multiply step)
10100 xor exclusive or of top elements of data stack
10101 and and of top elements of data stack
10111 + add top elements of data stack
11000 pop move top of return stack to data stack
11001 a move A to top of data stack
11010 dup duplicate top of data stack
11011 over duplicate second element of data stack
11100 push move to top of return stack
11101 a! move to A
11110 nop do nothing at all
11111 drop eliminate top of data stack

Primitive instructions are executed at three times the memory cycle rate. The bottom 5 bits in the 16 bit word (not counting the top bit indicating this as a primitive instruction word) are the first instruction to be executed, then the word is shifted 5 bits so the new bottom 5 bits are executed next and so on. The jump, call and literal instructions use any remaining bits in the instruction register as their argument. The jump and call instructions replace the corresponding bits in the program counter and so don't require the adder for their operation. So if the bottom 5 bits are used for a jump, then the lowest 10 bits in the PC are replaced with the value in the instruction register causing a jump to some location in the same 1 Kword "page" in memory. Using the second instruction as a jump or call will allow destinations in the same 32 byte "page" to be reached. When the last instruction is a literal, jump or call then the next word is used as the data allowing any bit pattern to be placed on the stack or in the PC.

And the presence of the self register requires some extra instructions:

code instruction details
00100 s! replace the high word of the top of the return stack (the low word is register R) with the value on the top of the data stack
00101 self push the value of the self register on the top of the data stack
00111 ? not defined
01110 ? not defined
10110 ? not defined

Note that the self register can't be directly loaded, but a s! instruction followed by a return will do the trick. The return stack is 32 bits wide and every time a 16 bit word is pushed on it (either a call or push instruction) the value of the self register supplies the other 16 bits. The self register is only changed by a return or send instruction (in the latter case it is loaded with the value on the top of the data stack).

In most memory accesses, the self register supplies the object ID for the address. One exception is for the @r+ and !r+ instructions which is the high word of the top of the return stack instead. This was done so that copying blocks of memory from one object to another wasn't too awkward.

Another exception is for instruction fetches. In that case a masked version of the self register is used. If the top bit of the self register is zero, then the object ID is also zero (this is used for integer objects), but if it is one then the mask depends on bits 14 and 13 of the self register:

bit 15 bits 14 and 13 bits 12 through 0
1 0 0 1 1 1 1 1 1 1 1 1 1 1 0 0
1 0 1 1 1 1 1 1 1 1 1 1 0 0 0 0
1 1 0 1 1 1 1 1 1 0 0 0 0 0 0 0
1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0

This is used by the software to implement "type objects".

The first four words of each object are found in an object table which takes up the first 128Kwords of memory. Just multiply the object ID by four and add the word number. The first two words contain the high and low 16 bits of the physical address of the rest of the object (if it is more than four words long).

Besides the processor, the FPGA implements a set of I/O devices:
  • ntsc video output - 8 bits per pixel (2 bits for value, 2 for saturation and 4 for hue. This allows 133 unique colors) at 280 by 210 pixels
  • smart LCD output - a 20 character by 4 line LCD, for example. It can also interface to a small graphical LCD.
  • serial I/O - can either be one RS232 interface with two control lines or two separate RS232 interfaces.
  • raw keyboard input - can have from 20 to 100 keys.